µGFX library fork

gdisp_lld_ili9225.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Created by Oleg Gerasimov <ogerasimov@gmail.com>
  3. * 10.08.2016
  4. */
  5. #include "gfx.h"
  6. #if GFX_USE_GDISP
  7. #if defined(GDISP_SCREEN_HEIGHT) || defined(GDISP_SCREEN_HEIGHT)
  8. #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
  9. #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
  10. #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
  11. COMPILER_WARNING("GDISP: This low level driver does not support setting a screen size. It is being ignored.")
  12. #endif
  13. #undef GDISP_SCREEN_WIDTH
  14. #undef GDISP_SCREEN_HEIGHT
  15. #endif
  16. #define GDISP_DRIVER_VMT GDISPVMT_ILI9225
  17. #include "gdisp_lld_config.h"
  18. #include "src/gdisp/gdisp_driver.h"
  19. #include "board_ILI9225.h"
  20. /*===========================================================================*/
  21. /* Driver local definitions. */
  22. /*===========================================================================*/
  23. #ifndef GDISP_SCREEN_HEIGHT
  24. #define GDISP_SCREEN_HEIGHT 220
  25. #endif
  26. #ifndef GDISP_SCREEN_WIDTH
  27. #define GDISP_SCREEN_WIDTH 176
  28. #endif
  29. #ifndef GDISP_INITIAL_CONTRAST
  30. #define GDISP_INITIAL_CONTRAST 100
  31. #endif
  32. #ifndef GDISP_INITIAL_BACKLIGHT
  33. #define GDISP_INITIAL_BACKLIGHT 100
  34. #endif
  35. #include "drivers/gdisp/ILI9225/ili9225.h"
  36. // Some common routines and macros
  37. #define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
  38. #define write_reg(g, reg, data) { write_cmd(g, reg); write_data(g, data); }
  39. // Serial write data for fast fill.
  40. #ifndef write_data_repeat
  41. #define write_data_repeat(g, data, count) { int i; for (i = 0; i < count; ++i) write_data (g, data) }
  42. #endif
  43. LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
  44. // No private area for this controller
  45. g->priv = 0;
  46. // Initialise the board interface
  47. init_board(g);
  48. // Hardware reset
  49. setpin_reset(g, TRUE);
  50. gfxSleepMilliseconds(20);
  51. setpin_reset(g, FALSE);
  52. gfxSleepMilliseconds(20);
  53. // Get the bus for the following initialisation commands
  54. acquire_bus(g);
  55. write_reg(g, ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB
  56. write_reg(g, ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC
  57. write_reg(g, ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3
  58. write_reg(g, ILI9225_POWER_CTRL4, 0x0000); // Set GVDD
  59. write_reg(g, ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage
  60. gfxSleepMilliseconds(40);
  61. // Power-on sequence
  62. write_reg(g, ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC
  63. write_reg(g, ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3
  64. write_reg(g, ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */
  65. write_reg(g, ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage
  66. write_reg(g, ILI9225_POWER_CTRL1, 0x0F00); // Set SAP,DSTB,STB
  67. gfxSleepMilliseconds(10);
  68. write_reg(g, ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC
  69. gfxSleepMilliseconds(50);
  70. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction
  71. write_reg(g, ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion
  72. write_reg(g, ILI9225_ENTRY_MODE, 0x1030); // set GRAM write direction and BGR=1.
  73. write_reg(g, ILI9225_DISP_CTRL1, 0x0000); // Display off
  74. write_reg(g, ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch
  75. write_reg(g, ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line
  76. write_reg(g, ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface
  77. write_reg(g, ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/
  78. write_reg(g, ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling
  79. write_reg(g, ILI9225_RAM_ADDR_SET1, 0x0000); // RAM Address
  80. write_reg(g, ILI9225_RAM_ADDR_SET2, 0x0000); // RAM Address
  81. // Set GRAM area
  82. write_reg(g, ILI9225_GATE_SCAN_CTRL, 0x0000);
  83. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB);
  84. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000);
  85. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000);
  86. write_reg(g, ILI9225_PARTIAL_DRIVING_POS1, 0x00DB);
  87. write_reg(g, ILI9225_PARTIAL_DRIVING_POS2, 0x0000);
  88. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF);
  89. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000);
  90. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB);
  91. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000);
  92. // Set GAMMA curve
  93. write_reg(g, ILI9225_GAMMA_CTRL1, 0x0000);
  94. write_reg(g, ILI9225_GAMMA_CTRL2, 0x0808);
  95. write_reg(g, ILI9225_GAMMA_CTRL3, 0x080A);
  96. write_reg(g, ILI9225_GAMMA_CTRL4, 0x000A);
  97. write_reg(g, ILI9225_GAMMA_CTRL5, 0x0A08);
  98. write_reg(g, ILI9225_GAMMA_CTRL6, 0x0808);
  99. write_reg(g, ILI9225_GAMMA_CTRL7, 0x0000);
  100. write_reg(g, ILI9225_GAMMA_CTRL8, 0x0A00);
  101. write_reg(g, ILI9225_GAMMA_CTRL9, 0x0710);
  102. write_reg(g, ILI9225_GAMMA_CTRL10, 0x0710);
  103. write_reg(g, ILI9225_DISP_CTRL1, 0x0012);
  104. gfxSleepMilliseconds(50);
  105. write_reg(g, ILI9225_DISP_CTRL1, 0x1017);
  106. release_bus(g);
  107. // Finish Init
  108. post_init_board(g);
  109. /* Turn on the back-light */
  110. set_backlight(g, GDISP_INITIAL_BACKLIGHT);
  111. /* Initialise the GDISP structure */
  112. g->g.Width = GDISP_SCREEN_WIDTH;
  113. g->g.Height = GDISP_SCREEN_HEIGHT;
  114. g->g.Orientation = GDISP_ROTATE_0;
  115. g->g.Powermode = powerOn;
  116. g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
  117. g->g.Contrast = GDISP_INITIAL_CONTRAST;
  118. return TRUE;
  119. }
  120. static void set_cursor(GDisplay *g) {
  121. switch(g->g.Orientation) {
  122. default:
  123. case GDISP_ROTATE_0:
  124. case GDISP_ROTATE_180:
  125. write_reg(g, ILI9225_RAM_ADDR_SET1, g->p.x);
  126. write_reg(g, ILI9225_RAM_ADDR_SET2, g->p.y);
  127. break;
  128. case GDISP_ROTATE_90:
  129. case GDISP_ROTATE_270:
  130. write_reg(g, ILI9225_RAM_ADDR_SET1, g->p.y);
  131. write_reg(g, ILI9225_RAM_ADDR_SET2, g->p.x);
  132. break;
  133. }
  134. write_cmd (g, ILI9225_GRAM_DATA_REG);
  135. }
  136. static void set_viewport(GDisplay *g) {
  137. switch(g->g.Orientation) {
  138. default:
  139. case GDISP_ROTATE_0:
  140. case GDISP_ROTATE_180:
  141. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR2, g->p.x);
  142. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR1, g->p.x + g->p.cx - 1);
  143. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR2, g->p.y);
  144. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR1, g->p.y + g->p.cy - 1);
  145. break;
  146. case GDISP_ROTATE_90:
  147. case GDISP_ROTATE_270:
  148. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR2, g->p.y);
  149. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR1, g->p.y + g->p.cy - 1);
  150. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR2, g->p.x);
  151. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR1, g->p.x + g->p.cx - 1);
  152. break;
  153. }
  154. }
  155. // temporary variables for saving viewport
  156. static int svx,svy,svcx,svcy,ws;
  157. #if GDISP_HARDWARE_STREAM_WRITE
  158. LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
  159. acquire_bus(g);
  160. set_viewport(g);
  161. // save viewport
  162. switch(g->g.Orientation) {
  163. default:
  164. case GDISP_ROTATE_0:
  165. case GDISP_ROTATE_180:
  166. svx = g->p.x; svy = g->p.y; svcx = g->p.cx; svcy = g->p.cy;
  167. break;
  168. case GDISP_ROTATE_90:
  169. case GDISP_ROTATE_270:
  170. svx = g->p.y; svy = g->p.x; svcx = g->p.cy; svcy = g->p.cx;
  171. break;
  172. }
  173. ws++;
  174. }
  175. LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
  176. LLDCOLOR_TYPE c;
  177. c = gdispColor2Native(g->p.color);
  178. write_data(g, c );
  179. }
  180. LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
  181. release_bus(g);
  182. if (ws)
  183. ws--;
  184. }
  185. LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
  186. set_cursor(g);
  187. }
  188. #endif
  189. LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
  190. set_cursor(g);
  191. gdisp_lld_write_color (g);
  192. }
  193. #if GDISP_HARDWARE_FILLS
  194. LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
  195. LLDCOLOR_TYPE c = gdispColor2Native(g->p.color);
  196. acquire_bus(g);
  197. // Set view port if drawing more than 1 line, or write not started
  198. if (g->p.cy != 1 || !ws)
  199. set_viewport(g);
  200. set_cursor(g);
  201. write_data_repeat (g,c,g->p.cx*g->p.cy);
  202. // Restore view port if write started and drawed more than 1 line
  203. if (g->p.cy != 1 && ws)
  204. {
  205. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR2, svx);
  206. write_reg(g, ILI9225_HORIZONTAL_WINDOW_ADDR1, svx + svcx - 1);
  207. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR2, svy);
  208. write_reg(g, ILI9225_VERTICAL_WINDOW_ADDR1, svy + svcy - 1);
  209. }
  210. release_bus(g);
  211. }
  212. #endif // GDISP_HARDWARE_FILLS
  213. #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
  214. LLDSPEC void gdisp_lld_control(GDisplay *g) {
  215. switch(g->p.x) {
  216. case GDISP_CONTROL_POWER:
  217. if (g->g.Powermode == (powermode_t)g->p.ptr)
  218. return;
  219. switch((powermode_t)g->p.ptr) {
  220. case powerOff:
  221. acquire_bus(g);
  222. write_reg(g, ILI9225_DISP_CTRL1, 0x0000); // Display off
  223. write_reg(g, ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB
  224. write_reg(g, ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC
  225. write_reg(g, ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3
  226. write_reg(g, ILI9225_POWER_CTRL4, 0x0000); // Set GVDD
  227. write_reg(g, ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage
  228. release_bus();
  229. set_backlight(g, 0);
  230. break;
  231. case powerSleep:
  232. case powerDeepSleep:
  233. acquire_bus(g);
  234. write_reg(g, ILI9225_DISP_CTRL1, 0x0000); // Display off
  235. write_reg(g, ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB
  236. write_reg(g, ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC
  237. write_reg(g, ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3
  238. write_reg(g, ILI9225_POWER_CTRL4, 0x0000); // Set GVDD
  239. gfxSleepMilliseconds(40);
  240. write_reg(g, ILI9225_POWER_CTRL1, 0x0004); // Set SAP,DSTB,STB
  241. release_bus(g);
  242. set_backlight(g, 0);
  243. break;
  244. case powerOn:
  245. acquire_bus(g);
  246. write_reg(g, ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB
  247. write_reg(g, ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC
  248. write_reg(g, ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3
  249. write_reg(g, ILI9225_POWER_CTRL4, 0x0000); // Set GVDD
  250. write_reg(g, ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage
  251. gfxSleepMilliseconds(40);
  252. // Power-on sequence
  253. write_reg(g, ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC
  254. write_reg(g, ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3
  255. write_reg(g, ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */
  256. write_reg(g, ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage
  257. write_reg(g, ILI9225_POWER_CTRL1, 0x0F00); // Set SAP,DSTB,STB
  258. gfxSleepMilliseconds(10);
  259. write_reg(g, ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC
  260. gfxSleepMilliseconds(50);
  261. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction
  262. write_reg(g, ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion
  263. write_reg(g, ILI9225_ENTRY_MODE, 0x1030); // set GRAM write direction and BGR=1.
  264. write_reg(g, ILI9225_DISP_CTRL1, 0x0000); // Display off
  265. write_reg(g, ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch
  266. write_reg(g, ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line
  267. write_reg(g, ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface
  268. write_reg(g, ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/
  269. write_reg(g, ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling
  270. // Set GRAM area
  271. write_reg(g, ILI9225_GATE_SCAN_CTRL, 0x0000);
  272. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB);
  273. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000);
  274. write_reg(g, ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000);
  275. write_reg(g, ILI9225_PARTIAL_DRIVING_POS1, 0x00DB);
  276. write_reg(g, ILI9225_PARTIAL_DRIVING_POS2, 0x0000);
  277. write_reg(g, ILI9225_DISP_CTRL1, 0x0012);
  278. gfxSleepMilliseconds(50);
  279. write_reg(g, ILI9225_DISP_CTRL1, 0x1017);
  280. release_bus(g);
  281. set_backlight(g, g->g.Backlight);
  282. break;
  283. default:
  284. return;
  285. }
  286. g->g.Powermode = (powermode_t)g->p.ptr;
  287. return;
  288. case GDISP_CONTROL_ORIENTATION:
  289. if (g->g.Orientation == (orientation_t)g->p.ptr)
  290. return;
  291. switch((orientation_t)g->p.ptr) {
  292. case GDISP_ROTATE_0: // correct
  293. acquire_bus(g);
  294. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x011C);
  295. write_reg(g, ILI9225_ENTRY_MODE, 0x1030);
  296. g->g.Height = GDISP_SCREEN_HEIGHT;
  297. g->g.Width = GDISP_SCREEN_WIDTH;
  298. release_bus(g);
  299. break;
  300. case GDISP_ROTATE_90:
  301. acquire_bus(g);
  302. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x031C);
  303. write_reg(g, ILI9225_ENTRY_MODE, 0x1038);
  304. g->g.Height = GDISP_SCREEN_WIDTH;
  305. g->g.Width = GDISP_SCREEN_HEIGHT;
  306. release_bus(g);
  307. break;
  308. case GDISP_ROTATE_180:
  309. acquire_bus(g);
  310. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x021C);
  311. write_reg(g, ILI9225_ENTRY_MODE, 0x1030);
  312. g->g.Height = GDISP_SCREEN_HEIGHT;
  313. g->g.Width = GDISP_SCREEN_WIDTH;
  314. release_bus(g);
  315. break;
  316. case GDISP_ROTATE_270:
  317. acquire_bus(g);
  318. write_reg(g, ILI9225_DRIVER_OUTPUT_CTRL, 0x001C);
  319. write_reg(g, ILI9225_ENTRY_MODE, 0x1038);
  320. g->g.Height = GDISP_SCREEN_WIDTH;
  321. g->g.Width = GDISP_SCREEN_HEIGHT;
  322. release_bus(g);
  323. break;
  324. default:
  325. return;
  326. }
  327. g->g.Orientation = (orientation_t)g->p.ptr;
  328. return;
  329. case GDISP_CONTROL_BACKLIGHT:
  330. if ((unsigned)g->p.ptr > 100)
  331. g->p.ptr = (void *)100;
  332. set_backlight(g, (unsigned)g->p.ptr);
  333. g->g.Backlight = (unsigned)g->p.ptr;
  334. return;
  335. default:
  336. return;
  337. }
  338. }
  339. #endif
  340. #endif /* GFX_USE_GDISP */