drv_lcd_st7735s(7774).c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #include "osi_api.h"
  13. #include "osi_log.h"
  14. #include "hal_gouda.h"
  15. #include "drv_lcd.h"
  16. #define LCD_DRV_ID_ST7735 0x7c89f0
  17. #define LCD_WIDTH 128
  18. #define LCD_HEIGHT 128
  19. static uint16_t st7735_line_mode;
  20. static bool st7735_farmk;
  21. #define LCM_WR_REG(Addr, Data) \
  22. { \
  23. while (halGoudaWriteReg(Addr, Data) != HAL_ERR_NO) \
  24. ; \
  25. }
  26. #define LCD_DataWrite_ST7735(Data) \
  27. { \
  28. while (halGoudaWriteData(Data) != HAL_ERR_NO) \
  29. ; \
  30. }
  31. #define LCD_CtrlWrite_ST7735(Cmd) \
  32. { \
  33. while (halGoudaWriteCmd(Cmd) != HAL_ERR_NO) \
  34. ; \
  35. }
  36. static void _st7735Close(void);
  37. static uint32_t _st7735ReadId(void);
  38. static void _st7735SleepIn(bool is_sleep);
  39. static void _st7735Init(void);
  40. static void _st7735Invalidate(void);
  41. static void _st7735InvalidateRect(
  42. uint16_t left, //the left value of the rectangel
  43. uint16_t top, //top of the rectangle
  44. uint16_t right, //right of the rectangle
  45. uint16_t bottom //bottom of the rectangle
  46. );
  47. static void _st7735SetDisplayWindow(
  48. uint16_t left, // start Horizon address
  49. uint16_t right, // end Horizon address
  50. uint16_t top, // start Vertical address
  51. uint16_t bottom // end Vertical address
  52. );
  53. static void _lcdDelayMs(int ms_delay)
  54. {
  55. osiDelayUS(ms_delay * 1000);
  56. }
  57. OSI_UNUSED static void _st7735SetDirection(lcdDirect_t direct_type)
  58. {
  59. OSI_LOGI(0, "lcd: _st7735SetDirection = %d", direct_type);
  60. switch (direct_type)
  61. {
  62. case LCD_DIRECT_NORMAL:
  63. LCD_CtrlWrite_ST7735(0x36);
  64. LCD_DataWrite_ST7735(0x00);
  65. break;
  66. case LCD_DIRECT_ROT_90:
  67. LCD_CtrlWrite_ST7735(0x36);
  68. LCD_DataWrite_ST7735(0x60);
  69. break;
  70. }
  71. LCD_CtrlWrite_ST7735(0x2c);
  72. }
  73. /******************************************************************************/
  74. // Description: Set the windows address to display, in this windows
  75. // color is refreshed.
  76. /******************************************************************************/
  77. static void _st7735SetDisplayWindow(
  78. uint16_t left, // start Horizon address
  79. uint16_t top, // start Vertical address
  80. uint16_t right, // end Horizon address
  81. uint16_t bottom // end Vertical address
  82. )
  83. {
  84. uint16_t newleft = left;
  85. uint16_t newtop = top;
  86. uint16_t newright = right;
  87. uint16_t newbottom = bottom;
  88. OSI_LOGI(0, "lcd:st7735SetDisplayWindow L = %d, top = %d, R = %d, bot = %d", left, top, right, bottom);
  89. LCD_CtrlWrite_ST7735(0x2a); // set hori start , end (left, right)
  90. LCD_DataWrite_ST7735((newleft >> 8) & 0xff); // left high 8 b
  91. LCD_DataWrite_ST7735(newleft & 0xff); // left low 8 b
  92. LCD_DataWrite_ST7735((newright >> 8) & 0xff); // right high 8 b
  93. LCD_DataWrite_ST7735(newright & 0xff); // right low 8 b
  94. LCD_CtrlWrite_ST7735(0x2b); // set vert start , end (top, bot)
  95. LCD_DataWrite_ST7735((newtop >> 8) & 0xff); // top high 8 b
  96. LCD_DataWrite_ST7735(newtop & 0xff); // top low 8 b
  97. LCD_DataWrite_ST7735((newbottom >> 8) & 0xff); // bot high 8 b
  98. LCD_DataWrite_ST7735(newbottom & 0xff); // bot low 8 b
  99. LCD_CtrlWrite_ST7735(0x2c); // recover memory write mode
  100. }
  101. /**************************************************************************************/
  102. // Description: initialize all LCD with LCDC MCU MODE and LCDC mcu mode
  103. /**************************************************************************************/
  104. static void _st7735Init(void)
  105. {
  106. OSI_LOGI(0, "lcd: _st7735Init ");
  107. LCD_CtrlWrite_ST7735(0x11); //Sleep out
  108. _lcdDelayMs(100); //Delay 120ms
  109. LCD_CtrlWrite_ST7735(0xB1);
  110. LCD_DataWrite_ST7735(0x05);
  111. LCD_DataWrite_ST7735(0x3A);
  112. LCD_DataWrite_ST7735(0x3A);
  113. LCD_CtrlWrite_ST7735(0xB2);
  114. LCD_DataWrite_ST7735(0x05);
  115. LCD_DataWrite_ST7735(0x3A);
  116. LCD_DataWrite_ST7735(0x3A);
  117. LCD_CtrlWrite_ST7735(0xB3);
  118. LCD_DataWrite_ST7735(0x05);
  119. LCD_DataWrite_ST7735(0x3A);
  120. LCD_DataWrite_ST7735(0x3A);
  121. LCD_DataWrite_ST7735(0x05);
  122. LCD_DataWrite_ST7735(0x3A);
  123. LCD_DataWrite_ST7735(0x3A);
  124. //------------------------------------End ST7735S Frame Rate-----------------------------------------//
  125. LCD_CtrlWrite_ST7735(0xB4); //Column inversion
  126. LCD_DataWrite_ST7735(0x03);
  127. LCD_CtrlWrite_ST7735(0xC0);
  128. LCD_DataWrite_ST7735(0x28);
  129. LCD_DataWrite_ST7735(0x08);
  130. LCD_DataWrite_ST7735(0x84);
  131. LCD_CtrlWrite_ST7735(0xC1);
  132. LCD_DataWrite_ST7735(0XC0);
  133. LCD_CtrlWrite_ST7735(0xC2);
  134. LCD_DataWrite_ST7735(0x0C);
  135. LCD_DataWrite_ST7735(0x00);
  136. LCD_CtrlWrite_ST7735(0xC3);
  137. LCD_DataWrite_ST7735(0x8C);
  138. LCD_DataWrite_ST7735(0x2A);
  139. LCD_CtrlWrite_ST7735(0xC4);
  140. LCD_DataWrite_ST7735(0x8A);
  141. LCD_DataWrite_ST7735(0xEE);
  142. //---------------------------------End ST7735S Power Sequence-------------------------------------//
  143. LCD_CtrlWrite_ST7735(0xC5); //VCOM
  144. LCD_DataWrite_ST7735(0x0C);
  145. LCD_CtrlWrite_ST7735(0x36); //MX, MY, RGB mode
  146. LCD_DataWrite_ST7735(0xA8);//C8//C0//A8//0x78//08 //屏幕选择设置 高四位 1111 配置
  147. //------------------------------------ST7735S Gamma Sequence-----------------------------------------//
  148. LCD_CtrlWrite_ST7735(0xE0);
  149. LCD_DataWrite_ST7735(0x05);
  150. LCD_DataWrite_ST7735(0x1A);
  151. LCD_DataWrite_ST7735(0x0C);
  152. LCD_DataWrite_ST7735(0x0E);
  153. LCD_DataWrite_ST7735(0x3A);
  154. LCD_DataWrite_ST7735(0x34);
  155. LCD_DataWrite_ST7735(0x2D);
  156. LCD_DataWrite_ST7735(0x2F);
  157. LCD_DataWrite_ST7735(0x2D);
  158. LCD_DataWrite_ST7735(0x2A);
  159. LCD_DataWrite_ST7735(0x2F);
  160. LCD_DataWrite_ST7735(0x3C);
  161. LCD_DataWrite_ST7735(0x00);
  162. LCD_DataWrite_ST7735(0x01);
  163. LCD_DataWrite_ST7735(0x02);
  164. LCD_DataWrite_ST7735(0x10);
  165. LCD_CtrlWrite_ST7735(0xE1);
  166. LCD_DataWrite_ST7735(0x04);
  167. LCD_DataWrite_ST7735(0x1B);
  168. LCD_DataWrite_ST7735(0x0D);
  169. LCD_DataWrite_ST7735(0x0E);
  170. LCD_DataWrite_ST7735(0x2D);
  171. LCD_DataWrite_ST7735(0x29);
  172. LCD_DataWrite_ST7735(0x24);
  173. LCD_DataWrite_ST7735(0x29);
  174. LCD_DataWrite_ST7735(0x28);
  175. LCD_DataWrite_ST7735(0x26);
  176. LCD_DataWrite_ST7735(0x31);
  177. LCD_DataWrite_ST7735(0x3B);
  178. LCD_DataWrite_ST7735(0x00);
  179. LCD_DataWrite_ST7735(0x00);
  180. LCD_DataWrite_ST7735(0x03);
  181. LCD_DataWrite_ST7735(0x12);
  182. //------------------------------------End ST7735S Gamma Sequence-----------------------------------------//
  183. LCD_CtrlWrite_ST7735(0x3A); //65k mode
  184. LCD_DataWrite_ST7735(0x05);
  185. LCD_CtrlWrite_ST7735(0x29); //Display on
  186. _lcdDelayMs(20);
  187. LCD_CtrlWrite_ST7735(0x2c);
  188. }
  189. static void _st7735SleepIn(bool is_sleep)
  190. {
  191. OSI_LOGI(0, "lcd: _st7735SleepIn, is_sleep = %d", is_sleep);
  192. if (is_sleep)
  193. {
  194. LCD_CtrlWrite_ST7735(0x28); //display off
  195. _lcdDelayMs(120);
  196. LCD_CtrlWrite_ST7735(0x10); // enter sleep mode
  197. }
  198. else
  199. {
  200. _st7735Init();
  201. }
  202. }
  203. static void _st7735Close(void)
  204. {
  205. OSI_LOGI(0, "lcd: in GC9304_Close");
  206. _st7735SleepIn(true);
  207. }
  208. static void _st7735Invalidate(void)
  209. {
  210. OSI_LOGI(0, "lcd: in _st7735Invalidate");
  211. _st7735SetDisplayWindow(0x0, 0x0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
  212. }
  213. void _st7735InvalidateRect(
  214. uint16_t left, //the left value of the rectangel
  215. uint16_t top, //top of the rectangle
  216. uint16_t right, //right of the rectangle
  217. uint16_t bottom //bottom of the rectangle
  218. )
  219. {
  220. OSI_LOGI(0, "lcd: _st7735InvalidateRect");
  221. left = (left >= LCD_WIDTH) ? LCD_WIDTH - 1 : left;
  222. right = (right >= LCD_WIDTH) ? LCD_WIDTH - 1 : right;
  223. top = (top >= LCD_HEIGHT) ? LCD_HEIGHT - 1 : top;
  224. bottom = (bottom >= LCD_HEIGHT) ? LCD_HEIGHT - 1 : bottom;
  225. if ((right < left) || (bottom < top))
  226. {
  227. OSI_ASSERT(false, "lcd: _st7735InvalidateRect error"); /*assert verified*/
  228. }
  229. _st7735SetDisplayWindow(left, top, right, bottom);
  230. }
  231. static void _st7735RotationInvalidateRect(uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, lcdAngle_t angle)
  232. {
  233. OSI_LOGI(0, "lcd: gc9305 gc9305RotationInvalidateRect");
  234. switch (angle)
  235. {
  236. case LCD_ANGLE_0:
  237. _st7735SetDisplayWindow(left, top, right, bottom);
  238. break;
  239. case LCD_ANGLE_90:
  240. _st7735SetDisplayWindow(left, top, bottom, right);
  241. break;
  242. case LCD_ANGLE_180:
  243. _st7735SetDisplayWindow(left, top, right, bottom);
  244. break;
  245. case LCD_ANGLE_270:
  246. _st7735SetDisplayWindow(left, top, bottom, right);
  247. break;
  248. default:
  249. _st7735SetDisplayWindow(left, top, right, bottom);
  250. break;
  251. }
  252. }
  253. static void _st7735EsdCheck(void)
  254. {
  255. OSI_LOGI(0, "lcd: st7735sEsdCheck");
  256. }
  257. static const lcdOperations_t st7735sOperations =
  258. {
  259. _st7735Init,
  260. _st7735SleepIn,
  261. _st7735EsdCheck,
  262. _st7735SetDisplayWindow,
  263. _st7735InvalidateRect,
  264. _st7735Invalidate,
  265. _st7735Close,
  266. _st7735RotationInvalidateRect,
  267. NULL,
  268. _st7735ReadId,
  269. };
  270. const lcdSpec_t g_lcd_st7735s =
  271. {
  272. LCD_DRV_ID_ST7735,
  273. LCD_WIDTH,
  274. LCD_HEIGHT,
  275. HAL_GOUDA_SPI_LINE_4,
  276. LCD_CTRL_SPI,
  277. (lcdOperations_t *)&st7735sOperations,
  278. false,
  279. 0x2a000,
  280. 10000000,// 500000, //10000000, 10M
  281. };
  282. static uint32_t _st7735ReadId(void)
  283. {
  284. uint32_t ret_id = 0;
  285. HAL_ERR_T r_err;
  286. uint8_t id[4] = {0};
  287. OSI_LOGI(0, "lcd:st7735ReadId \n");
  288. // halPmuSwitchPower(HAL_POWER_LCD, true, true);
  289. _lcdDelayMs(10);
  290. st7735_farmk = g_lcd_st7735s.is_use_fmark;
  291. st7735_line_mode = g_lcd_st7735s.bus_mode;
  292. halGoudaReadConfig(st7735_line_mode, g_lcd_st7735s.is_use_fmark, g_lcd_st7735s.fmark_delay);
  293. _lcdDelayMs(140);
  294. //hwp_analogReg->pad_spi_lcd_cfg2 |= ANALOG_REG_PAD_SPI_LCD_SIO_SPU;
  295. _lcdDelayMs(10);
  296. r_err = halGoudaReadData(0x04, id, 4);
  297. //hwp_analogReg->pad_spi_lcd_cfg2 = hwp_analogReg->pad_spi_lcd_cfg2&(~ANALOG_REG_PAD_SPI_LCD_SIO_SPU);
  298. OSI_LOGI(0, "lcd:st7735ReadId LCM: 0x%0x, 0x%x, 0x%0x (read return : %d)\n", id[2], id[1], id[3], r_err);
  299. ret_id = ((id[3] << 16) | (id[2] << 8) | id[1]);
  300. if (LCD_DRV_ID_ST7735 == ret_id)
  301. {
  302. OSI_LOGI(0, "lcd: is using !");
  303. }
  304. halGoudaClose();
  305. // halPmuSwitchPower(HAL_POWER_LCD, false, false);
  306. // osiDebugEvent(0x666661d);osiDebugEvent(ret_id);
  307. return ret_id;
  308. }