µGFX library fork

gdisp_lld_ST7735.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Created by Oleg Gerasimov <ogerasimov@gmail.com>
  3. * 14.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_ST7735
  17. #include "gdisp_lld_config.h"
  18. #include "src/gdisp/gdisp_driver.h"
  19. #include "board_ST7735.h"
  20. /*===========================================================================*/
  21. /* Driver local definitions. */
  22. /*===========================================================================*/
  23. #ifndef GDISP_SCREEN_HEIGHT
  24. #define GDISP_SCREEN_HEIGHT 160
  25. #endif
  26. #ifndef GDISP_SCREEN_WIDTH
  27. #define GDISP_SCREEN_WIDTH 128
  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. // Define one of supported type, if not defined yet
  36. #if !defined(ST7735_TYPE_R) && !defined(ST7735_TYPE_B)
  37. // It seems all modern boards is 7735R
  38. #define ST7735_TYPE_R TRUE
  39. #endif
  40. // Define one of supported color packing, if not defined yet
  41. #if !defined(ST7735_COLOR_RGB) && !defined(ST7735_COLOR_BRG)
  42. // It seems all modern boards is RGB
  43. #define ST7735_COLOR_RGB TRUE
  44. #endif
  45. // Strange boars with shifted coords
  46. #if !defined (ST7735_SHIFTED_COORDS)
  47. #define ST7735_SHIFTED_COORDS FALSE
  48. #endif
  49. #if ST7735_COLOR_RGB
  50. #define ST7735_MADCTRL_COLOR 0x00
  51. #else
  52. #define ST7735_MADCTRL_COLOR 0x08
  53. #endif
  54. #if ST7735_SHIFTED_COORDS
  55. #define ST7735_COL_SHIFT 2
  56. #define ST7735_ROW_SHIFT 1
  57. #else
  58. #define ST7735_COL_SHIFT 0
  59. #define ST7735_ROW_SHIFT 0
  60. #endif
  61. #include "drivers/gdisp/ST7735/ST7735.h"
  62. // Some common routines and macros
  63. #define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
  64. #define write_reg(g, reg, data) { write_cmd(g, reg); write_data(g, data); }
  65. // Serial write data for fast fill.
  66. #ifndef write_data_repeat
  67. #define write_data_repeat(g, data, count) { int i; for (i = 0; i < count; ++i) write_data (g, data) }
  68. #endif
  69. // Commands list copied from https://github.com/adafruit/Adafruit-ST7735-Library
  70. #define DELAY 0x80
  71. #if ST7735_TYPE_B
  72. static const unsigned char
  73. init_cmds[] = { // Initialization commands for 7735B screens
  74. 16, // 16 commands in list:
  75. ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay
  76. 50, // 50 ms delay
  77. ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay
  78. 255, // 255 = 500 ms delay
  79. ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay:
  80. 0x05, // 16-bit color
  81. 10, // 10 ms delay
  82. ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay:
  83. 0x00, // fastest refresh
  84. 0x06, // 6 lines front porch
  85. 0x03, // 3 lines back porch
  86. 10, // 10 ms delay
  87. ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg:
  88. ST7735_MADCTRL_COLOR, // Row addr/col addr, bottom to top refresh
  89. ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay:
  90. 0x15, // 1 clk cycle nonoverlap, 2 cycle gate
  91. // rise, 3 cycle osc equalize
  92. 0x02, // Fix on VTL
  93. ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg:
  94. 0x0, // Line inversion
  95. ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay:
  96. 0x02, // GVDD = 4.7V
  97. 0x70, // 1.0uA
  98. 10, // 10 ms delay
  99. ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay:
  100. 0x05, // VGH = 14.7V, VGL = -7.35V
  101. ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay:
  102. 0x01, // Opamp current small
  103. 0x02, // Boost frequency
  104. ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay:
  105. 0x3C, // VCOMH = 4V
  106. 0x38, // VCOML = -1.1V
  107. 10, // 10 ms delay
  108. ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay:
  109. 0x11, 0x15,
  110. ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay:
  111. 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what
  112. 0x21, 0x1B, 0x13, 0x19, // these config values represent)
  113. 0x17, 0x15, 0x1E, 0x2B,
  114. 0x04, 0x05, 0x02, 0x0E,
  115. ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay:
  116. 0x0B, 0x14, 0x08, 0x1E, // (ditto)
  117. 0x22, 0x1D, 0x18, 0x1E,
  118. 0x1B, 0x1A, 0x24, 0x2B,
  119. 0x06, 0x06, 0x02, 0x0F,
  120. 10, // 10 ms delay
  121. ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay
  122. 10, // 10 ms delay
  123. ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay
  124. 255 }; // 255 = 500 ms delay
  125. #elif ST7735_TYPE_R
  126. static const unsigned char
  127. init_cmds[] = { // Init for 7735R, part 1 (red or green tab)
  128. 19, // 19 commands in list:
  129. ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay
  130. 150, // 150 ms delay
  131. ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay
  132. 255, // 500 ms delay
  133. ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args:
  134. 0x00, 0x0, 0x0, // Rate = fosc/(0+40) * (LINE+0+0)
  135. ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args:
  136. 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D)
  137. ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args:
  138. 0x01, 0x2C, 0x2D, // Dot inversion mode
  139. 0x01, 0x2C, 0x2D, // Line inversion mode
  140. ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay:
  141. 0x07, // No inversion
  142. ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay:
  143. 0xA2,
  144. 0x02, // -4.6V
  145. 0x44, // mode 3
  146. ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay:
  147. 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
  148. ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay:
  149. 0x0A, // Opamp current small
  150. 0x00, // Boost frequency
  151. ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay:
  152. 0x8A, // BCLK/2, Opamp current small & Medium low
  153. 0x2A,
  154. ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay:
  155. 0x8A, 0xEE,
  156. ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay:
  157. 0x0E,
  158. ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay
  159. ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg:
  160. 0xC0|ST7735_MADCTRL_COLOR, // row addr/col addr, bottom to top refresh
  161. ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay:
  162. 0x05, // 16-bit color
  163. ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay:
  164. 0x02, 0x1c, 0x07, 0x12,
  165. 0x37, 0x32, 0x29, 0x2d,
  166. 0x29, 0x25, 0x2B, 0x39,
  167. 0x00, 0x01, 0x03, 0x10,
  168. ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay:
  169. 0x03, 0x1d, 0x07, 0x06,
  170. 0x2E, 0x2C, 0x29, 0x2D,
  171. 0x2E, 0x2E, 0x37, 0x3F,
  172. 0x00, 0x00, 0x02, 0x10,
  173. ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay
  174. 10, // 10 ms delay
  175. ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay
  176. 100
  177. }; // 100 ms delay
  178. #endif
  179. static void execute_cmds (const uint8_t *addr) {
  180. unsigned int cmds = *addr++;
  181. while (cmds--) {
  182. write_cmd (g, *addr++);
  183. unsigned int args = *addr++;
  184. unsigned int ms = args & DELAY;
  185. args &= ~DELAY;
  186. while(args--)
  187. write_data_byte (g,*addr++);
  188. if (ms) {
  189. ms = *addr++;
  190. gfxSleepMilliseconds(ms==255?500:ms);
  191. }
  192. }
  193. }
  194. LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
  195. // No private area for this controller
  196. g->priv = 0;
  197. // Initialise the board interface
  198. init_board(g);
  199. // Hardware reset
  200. setpin_reset(g, TRUE);
  201. gfxSleepMilliseconds(20);
  202. setpin_reset(g, FALSE);
  203. gfxSleepMilliseconds(20);
  204. // Get the bus for the following initialisation commands
  205. acquire_bus(g);
  206. execute_cmds (init_cmds);
  207. release_bus(g);
  208. // Finish Init
  209. post_init_board(g);
  210. /* Turn on the back-light */
  211. set_backlight(g, GDISP_INITIAL_BACKLIGHT);
  212. /* Initialise the GDISP structure */
  213. g->g.Width = GDISP_SCREEN_WIDTH;
  214. g->g.Height = GDISP_SCREEN_HEIGHT;
  215. g->g.Orientation = GDISP_ROTATE_0;
  216. g->g.Powermode = powerOn;
  217. g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
  218. g->g.Contrast = GDISP_INITIAL_CONTRAST;
  219. return TRUE;
  220. }
  221. static void set_viewport(GDisplay *g) {
  222. write_cmd (g, ST7735_CASET);
  223. write_data (g, g->p.x+ST7735_COL_SHIFT);
  224. write_data (g, g->p.x+g->p.cx-1+ST7735_COL_SHIFT);
  225. write_cmd (g, ST7735_RASET);
  226. write_data (g, g->p.y+ST7735_ROW_SHIFT);
  227. write_data (g, g->p.y+g->p.cy-1+ST7735_ROW_SHIFT);
  228. write_cmd (g, ST7735_RAMWR);
  229. }
  230. #if GDISP_HARDWARE_STREAM_WRITE
  231. LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
  232. acquire_bus(g);
  233. set_viewport(g);
  234. }
  235. LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
  236. LLDCOLOR_TYPE c;
  237. c = gdispColor2Native(g->p.color);
  238. write_data(g, c );
  239. }
  240. LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
  241. release_bus(g);
  242. }
  243. #endif
  244. LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
  245. set_viewport(g);
  246. gdisp_lld_write_color (g);
  247. }
  248. #if GDISP_HARDWARE_FILLS
  249. LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
  250. LLDCOLOR_TYPE c = gdispColor2Native(g->p.color);
  251. acquire_bus(g);
  252. set_viewport (g);
  253. write_data_repeat (g,c,g->p.cx*g->p.cy);
  254. release_bus(g);
  255. }
  256. #endif // GDISP_HARDWARE_FILLS
  257. #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
  258. LLDSPEC void gdisp_lld_control(GDisplay *g) {
  259. switch(g->p.x) {
  260. case GDISP_CONTROL_POWER:
  261. if (g->g.Powermode == (powermode_t)g->p.ptr)
  262. return;
  263. switch((powermode_t)g->p.ptr) {
  264. case powerOff:
  265. acquire_bus(g);
  266. // not implemented
  267. release_bus();
  268. set_backlight(g, 0);
  269. break;
  270. case powerSleep:
  271. case powerDeepSleep:
  272. // not implemented
  273. acquire_bus(g);
  274. release_bus(g);
  275. set_backlight(g, 0);
  276. break;
  277. case powerOn:
  278. acquire_bus(g);
  279. // not implemented
  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:
  293. acquire_bus(g);
  294. write_cmd(g, ST7735_MADCTL);
  295. write_data_byte(g, 0xC0|ST7735_MADCTRL_COLOR);
  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_cmd(g, ST7735_MADCTL);
  303. write_data_byte(g, 0xA0|ST7735_MADCTRL_COLOR);
  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_cmd(g, ST7735_MADCTL);
  311. write_data_byte(g, 0x00|ST7735_MADCTRL_COLOR);
  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_cmd(g, ST7735_MADCTL);
  319. write_data_byte(g, 0x60|ST7735_MADCTRL_COLOR);
  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 */