gc9a01.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. //--------------------------------------------------------------------------------------------------------
  2. // Nadyrshin Ruslan - [YouTube-channel: https://www.youtube.com/channel/UChButpZaL5kUUl_zTyIDFkQ]
  3. // Liyanboy74
  4. //--------------------------------------------------------------------------------------------------------
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "driver/gpio.h"
  10. #include "driver/spi_master.h"
  11. #include "driver/ledc.h"
  12. #include "sdkconfig.h"
  13. #include "gc9a01.h"
  14. #if (CONFIG_GC9A01_RESET_USED)
  15. #define RESET_HIGH() gpio_set_level(CONFIG_GC9A01_PIN_NUM_RST,1)
  16. #define RESET_LOW() gpio_set_level(CONFIG_GC9A01_PIN_NUM_RST,0)
  17. #endif
  18. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  19. #define BLK_HIGH() gpio_set_level(CONFIG_GC9A01_PIN_NUM_BCKL,1)
  20. #define BLK_LOW() gpio_set_level(CONFIG_GC9A01_PIN_NUM_BCKL,0)
  21. #endif
  22. #define Cmd_SLPIN 0x10
  23. #define Cmd_SLPOUT 0x11
  24. #define Cmd_INVOFF 0x20
  25. #define Cmd_INVON 0x21
  26. #define Cmd_DISPOFF 0x28
  27. #define Cmd_DISPON 0x29
  28. #define Cmd_CASET 0x2A
  29. #define Cmd_RASET 0x2B
  30. #define Cmd_RAMWR 0x2C
  31. #define Cmd_TEON 0x35 // Tearing effect line ON
  32. #define Cmd_MADCTL 0x36 // Memory data access control
  33. #define Cmd_COLMOD 0x3A // Pixel format set
  34. #define Cmd_DisplayFunctionControl 0xB6
  35. #define Cmd_PWCTR1 0xC1 // Power control 1
  36. #define Cmd_PWCTR2 0xC3 // Power control 2
  37. #define Cmd_PWCTR3 0xC4 // Power control 3
  38. #define Cmd_PWCTR4 0xC9 // Power control 4
  39. #define Cmd_PWCTR7 0xA7 // Power control 7
  40. #define Cmd_FRAMERATE 0xE8
  41. #define Cmd_InnerReg1Enable 0xFE
  42. #define Cmd_InnerReg2Enable 0xEF
  43. #define Cmd_GAMMA1 0xF0 // Set gamma 1
  44. #define Cmd_GAMMA2 0xF1 // Set gamma 2
  45. #define Cmd_GAMMA3 0xF2 // Set gamma 3
  46. #define Cmd_GAMMA4 0xF3 // Set gamma 4
  47. #define ColorMode_RGB_16bit 0x50
  48. #define ColorMode_RGB_18bit 0x60
  49. #define ColorMode_MCU_12bit 0x03
  50. #define ColorMode_MCU_16bit 0x05
  51. #define ColorMode_MCU_18bit 0x06
  52. #define MADCTL_MY 0x80
  53. #define MADCTL_MX 0x40
  54. #define MADCTL_MV 0x20
  55. #define MADCTL_ML 0x10
  56. #define MADCTL_BGR 0x08
  57. #define MADCTL_MH 0x04
  58. uint8_t GC9A01_X_Start = 0, GC9A01_Y_Start = 0;
  59. #if (CONFIG_GC9A01_BUFFER_MODE)
  60. #if (CONFIG_GC9A01_BUFFER_MODE_PSRAM)
  61. uint16_t *ScreenBuff = NULL;
  62. #else
  63. DMA_ATTR uint16_t ScreenBuff[GC9A01_Height * GC9A01_Width];
  64. #endif
  65. #endif
  66. //SPI Config
  67. spi_device_handle_t spi;
  68. spi_host_device_t LCD_HOST=CONFIG_GC9A01_SPI_HOST;
  69. //LEDC Config
  70. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  71. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_MODE)
  72. ledc_channel_config_t ledc_cConfig;
  73. ledc_timer_config_t ledc_tConfig;
  74. void LEDC_PWM_Duty_Set(uint8_t DutyP);
  75. #endif
  76. #endif
  77. /*
  78. The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct.
  79. */
  80. typedef struct {
  81. uint8_t cmd;
  82. uint8_t data[16];
  83. uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
  84. } lcd_init_cmd_t;
  85. static const lcd_init_cmd_t lcd_init_cmds[]={
  86. {0xef,{0},0},
  87. {0xeb,{0x14},1},
  88. {0xfe,{0},0},
  89. {0xef,{0},0},
  90. {0xeb,{0x14},1},
  91. {0x84,{0x40},1},
  92. {0x85,{0xff},1},
  93. {0x86,{0xff},1},
  94. {0x87,{0xff},1},
  95. {0x88,{0x0a},1},
  96. {0x89,{0x21},1},
  97. {0x8a,{0x00},1},
  98. {0x8b,{0x80},1},
  99. {0x8c,{0x01},1},
  100. {0x8d,{0x01},1},
  101. {0x8e,{0xff},1},
  102. {0x8f,{0xff},1},
  103. {Cmd_DisplayFunctionControl,{0x00,0x20},2},// Scan direction S360 -> S1
  104. //{Cmd_MADCTL,{0x08},1},//MemAccessModeSet(0, 0, 0, 1);
  105. //{Cmd_COLMOD,{ColorMode_MCU_16bit&0x77},1},
  106. {0x90,{0x08,0x08,0x08,0x08},4},
  107. {0xbd,{0x06},1},
  108. {0xbc,{0x00},1},
  109. {0xff,{0x60,0x01,0x04},3},
  110. {Cmd_PWCTR2,{0x13},1},
  111. {Cmd_PWCTR3,{0x13},1},
  112. {Cmd_PWCTR4,{0x22},1},
  113. {0xbe,{0x11},1},
  114. {0xe1,{0x10,0x0e},2},
  115. {0xdf,{0x21,0x0c,0x02},3},
  116. {Cmd_GAMMA1,{0x45,0x09,0x08,0x08,0x26,0x2a},6},
  117. {Cmd_GAMMA2,{0x43,0x70,0x72,0x36,0x37,0x6f},6},
  118. {Cmd_GAMMA3,{0x45,0x09,0x08,0x08,0x26,0x2a},6},
  119. {Cmd_GAMMA4,{0x43,0x70,0x72,0x36,0x37,0x6f},6},
  120. {0xed,{0x1b,0x0b},2},
  121. {0xae,{0x77},1},
  122. {0xcd,{0x63},1},
  123. {0x70,{0x07,0x07,0x04,0x0e,0x0f,0x09,0x07,0x08,0x03},9},
  124. {Cmd_FRAMERATE,{0x34},1},// 4 dot inversion
  125. {0x62,{0x18,0x0D,0x71,0xED,0x70,0x70,0x18,0x0F,0x71,0xEF,0x70,0x70},12},
  126. {0x63,{0x18,0x11,0x71,0xF1,0x70,0x70,0x18,0x13,0x71,0xF3,0x70,0x70},12},
  127. {0x64,{0x28,0x29,0xF1,0x01,0xF1,0x00,0x07},7},
  128. {0x66,{0x3C,0x00,0xCD,0x67,0x45,0x45,0x10,0x00,0x00,0x00},10},
  129. {0x67,{0x00,0x3C,0x00,0x00,0x00,0x01,0x54,0x10,0x32,0x98},10},
  130. {0x74,{0x10,0x85,0x80,0x00,0x00,0x4E,0x00},7},
  131. {0x98,{0x3e,0x07},2},
  132. {Cmd_TEON,{0},0},// Tearing effect line on
  133. {0, {0}, 0xff},//END
  134. };
  135. //This function is called (in irq context!) just before a transmission starts. It will
  136. //set the D/C line to the value indicated in the user field.
  137. static IRAM_ATTR void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
  138. {
  139. int dc=(int)t->user;
  140. gpio_set_level(CONFIG_GC9A01_PIN_NUM_DC, dc);
  141. }
  142. /* Send a command to the LCD. Uses spi_device_polling_transmit, which waits
  143. * until the transfer is complete.
  144. *
  145. * Since command transactions are usually small, they are handled in polling
  146. * mode for higher speed. The overhead of interrupt transactions is more than
  147. * just waiting for the transaction to complete.
  148. */
  149. void lcd_cmd(uint8_t cmd)
  150. {
  151. esp_err_t ret;
  152. spi_transaction_t t;
  153. memset(&t, 0, sizeof(t)); //Zero out the transaction
  154. t.length=8; //Command is 8 bits
  155. t.tx_buffer=&cmd; //The data is the cmd itself
  156. t.user=(void*)0; //D/C needs to be set to 0
  157. ret=spi_device_polling_transmit(spi, &t); //Transmit!
  158. assert(ret==ESP_OK); //Should have had no issues.
  159. }
  160. /* Send data to the LCD. Uses spi_device_polling_transmit, which waits until the
  161. * transfer is complete.
  162. *
  163. * Since data transactions are usually small, they are handled in polling
  164. * mode for higher speed. The overhead of interrupt transactions is more than
  165. * just waiting for the transaction to complete.
  166. */
  167. void lcd_data(const uint8_t *data, int len)
  168. {
  169. esp_err_t ret;
  170. if (len==0) return; //no need to send anything
  171. /*
  172. On certain MC's the max SPI DMA transfer length might be smaller than the buffer. We then have to split the transmissions.
  173. */
  174. int offset = 0;
  175. do {
  176. spi_transaction_t t;
  177. memset(&t, 0, sizeof(t)); //Zero out the transaction
  178. int tx_len = ((len - offset) < SPI_MAX_DMA_LEN) ? (len - offset) : SPI_MAX_DMA_LEN;
  179. t.length=tx_len * 8; //Len is in bytes, transaction length is in bits.
  180. t.tx_buffer= data + offset; //Data
  181. t.user=(void*)1; //D/C needs to be set to 1
  182. ret=spi_device_polling_transmit(spi, &t); //Transmit!
  183. assert(ret==ESP_OK); //Should have had no issues.
  184. offset += tx_len; // Add the transmission length to the offset
  185. }
  186. while (offset < len);
  187. }
  188. void lcd_send_byte(uint8_t Data)
  189. {
  190. lcd_data(&Data,1);
  191. }
  192. void delay_ms (uint32_t Delay_ms)
  193. {
  194. vTaskDelay(Delay_ms/portTICK_PERIOD_MS);
  195. }
  196. uint16_t GC9A01_GetWidth() {
  197. return GC9A01_Width;
  198. }
  199. uint16_t GC9A01_GetHeight() {
  200. return GC9A01_Height;
  201. }
  202. void GC9A01_HardReset(void) {
  203. #if (CONFIG_GC9A01_RESET_USED)
  204. RESET_LOW();
  205. delay_ms(10);
  206. RESET_HIGH();
  207. delay_ms(150);
  208. #endif
  209. }
  210. void GC9A01_SleepMode(uint8_t Mode) {
  211. if (Mode)
  212. lcd_cmd(Cmd_SLPIN);
  213. else
  214. lcd_cmd(Cmd_SLPOUT);
  215. delay_ms(500);
  216. }
  217. void GC9A01_InversionMode(uint8_t Mode) {
  218. if (Mode)
  219. lcd_cmd(Cmd_INVON);
  220. else
  221. lcd_cmd(Cmd_INVOFF);
  222. }
  223. void GC9A01_DisplayPower(uint8_t On) {
  224. if (On)
  225. lcd_cmd(Cmd_DISPON);
  226. else
  227. lcd_cmd(Cmd_DISPOFF);
  228. }
  229. static void ColumnSet(uint16_t ColumnStart, uint16_t ColumnEnd) {
  230. if (ColumnStart > ColumnEnd)
  231. return;
  232. if (ColumnEnd > GC9A01_Width)
  233. return;
  234. ColumnStart += GC9A01_X_Start;
  235. ColumnEnd += GC9A01_X_Start;
  236. lcd_cmd(Cmd_CASET);
  237. lcd_send_byte(ColumnStart >> 8);
  238. lcd_send_byte(ColumnStart & 0xFF);
  239. lcd_send_byte(ColumnEnd >> 8);
  240. lcd_send_byte(ColumnEnd & 0xFF);
  241. }
  242. static void RowSet(uint16_t RowStart, uint16_t RowEnd) {
  243. if (RowStart > RowEnd)
  244. return;
  245. if (RowEnd > GC9A01_Height)
  246. return;
  247. RowStart += GC9A01_Y_Start;
  248. RowEnd += GC9A01_Y_Start;
  249. lcd_cmd(Cmd_RASET);
  250. lcd_send_byte(RowStart >> 8);
  251. lcd_send_byte(RowStart & 0xFF);
  252. lcd_send_byte(RowEnd >> 8);
  253. lcd_send_byte(RowEnd & 0xFF);
  254. }
  255. void GC9A01_SetWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
  256. ColumnSet(x0, x1);
  257. RowSet(y0, y1);
  258. lcd_cmd(Cmd_RAMWR);
  259. }
  260. static void ColorModeSet(uint8_t ColorMode) {
  261. lcd_cmd(Cmd_COLMOD);
  262. lcd_send_byte(ColorMode & 0x77);
  263. }
  264. static void MemAccessModeSet(uint8_t Rotation, uint8_t VertMirror,
  265. uint8_t HorizMirror, uint8_t IsBGR) {
  266. uint8_t Ret=0;
  267. Rotation &= 7;
  268. lcd_cmd(Cmd_MADCTL);
  269. switch (Rotation) {
  270. case 0:
  271. Ret = 0;
  272. break;
  273. case 1:
  274. Ret = MADCTL_MX;
  275. break;
  276. case 2:
  277. Ret = MADCTL_MY;
  278. break;
  279. case 3:
  280. Ret = MADCTL_MX | MADCTL_MY;
  281. break;
  282. case 4:
  283. Ret = MADCTL_MV;
  284. break;
  285. case 5:
  286. Ret = MADCTL_MV | MADCTL_MX;
  287. break;
  288. case 6:
  289. Ret = MADCTL_MV | MADCTL_MY;
  290. break;
  291. case 7:
  292. Ret = MADCTL_MV | MADCTL_MX | MADCTL_MY;
  293. break;
  294. }
  295. if (VertMirror)
  296. Ret = MADCTL_ML;
  297. if (HorizMirror)
  298. Ret = MADCTL_MH;
  299. if (IsBGR)
  300. Ret |= MADCTL_BGR;
  301. lcd_send_byte(Ret);
  302. }
  303. void GC9A01_SetBL(uint8_t Value)
  304. {
  305. if (Value > 100) Value = 100;
  306. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  307. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_MODE)
  308. LEDC_PWM_Duty_Set(Value);
  309. #else
  310. if (Value) BLK_HIGH();
  311. else BLK_LOW();
  312. #endif
  313. #endif
  314. }
  315. //Direct Mode
  316. #if (!CONFIG_GC9A01_BUFFER_MODE)
  317. void GC9A01_RamWrite(uint16_t *pBuff, uint16_t Len)
  318. {
  319. while (Len--)
  320. {
  321. lcd_send_byte(*pBuff >> 8);
  322. lcd_send_byte(*pBuff & 0xFF);
  323. }
  324. }
  325. void GC9A01_DrawPixel(int16_t x, int16_t y, uint16_t color)
  326. {
  327. if ((x < 0) ||(x >= GC9A01_Width) || (y < 0) || (y >= GC9A01_Height))
  328. return;
  329. GC9A01_SetWindow(x, y, x, y);
  330. GC9A01_RamWrite(&color, 1);
  331. }
  332. void GC9A01_FillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
  333. {
  334. if ((x >= GC9A01_Width) || (y >= GC9A01_Height))
  335. return;
  336. if ((x + w) > GC9A01_Width)
  337. w = GC9A01_Width - x;
  338. if ((y + h) > GC9A01_Height)
  339. h = GC9A01_Height - y;
  340. GC9A01_SetWindow(x, y, x + w - 1, y + h - 1);
  341. for (uint32_t i = 0; i < (h * w); i++)
  342. GC9A01_RamWrite(&color, 1);
  343. }
  344. //Buffer mode
  345. #else
  346. static void SwapBytes(uint16_t *color) {
  347. uint8_t temp = *color >> 8;
  348. *color = (*color << 8) | temp;
  349. }
  350. void GC9A01_DrawPixel(int16_t x, int16_t y, uint16_t color) {
  351. if ((x < 0) || (x >= GC9A01_Width) || (y < 0) || (y >= GC9A01_Height))
  352. return;
  353. SwapBytes(&color);
  354. ScreenBuff[y * GC9A01_Width + x] = color;
  355. }
  356. uint16_t GC9A01_GetPixel(int16_t x, int16_t y) {
  357. if ((x < 0) || (x >= GC9A01_Width) || (y < 0) || (y >= GC9A01_Height))
  358. return 0;
  359. uint16_t color = ScreenBuff[y * GC9A01_Width + x];
  360. SwapBytes(&color);
  361. return color;
  362. }
  363. void GC9A01_FillRect(int16_t x, int16_t y, int16_t w, int16_t h,
  364. uint16_t color) {
  365. if ((w <= 0) || (h <= 0) || (x >= GC9A01_Width) || (y >= GC9A01_Height))
  366. return;
  367. if (x < 0) {
  368. w += x;
  369. x = 0;
  370. }
  371. if (y < 0) {
  372. h += y;
  373. y = 0;
  374. }
  375. if ((w <= 0) || (h <= 0))
  376. return;
  377. if ((x + w) > GC9A01_Width)
  378. w = GC9A01_Width - x;
  379. if ((y + h) > GC9A01_Height)
  380. h = GC9A01_Height - y;
  381. SwapBytes(&color);
  382. for (uint16_t row = 0; row < h; row++) {
  383. for (uint16_t col = 0; col < w; col++)
  384. //GC9A01_DrawPixel(col, row, color);
  385. ScreenBuff[(y + row) * GC9A01_Width + x + col] = color;
  386. }
  387. }
  388. void GC9A01_Update()
  389. {
  390. int len = GC9A01_Width * GC9A01_Height;
  391. GC9A01_SetWindow(0, 0, GC9A01_Width - 1, GC9A01_Height - 1);
  392. lcd_data((uint8_t*) &ScreenBuff[0], len*2);
  393. }
  394. void GC9A01_Clear(void)
  395. {
  396. GC9A01_FillRect(0, 0, GC9A01_Width, GC9A01_Height, 0x0000);
  397. }
  398. #endif
  399. static void gc9a01_GPIO_init(void)
  400. {
  401. gpio_config_t gpiocfg={
  402. .pin_bit_mask= ((uint64_t)1UL<<CONFIG_GC9A01_PIN_NUM_DC),
  403. .mode=GPIO_MODE_OUTPUT,
  404. .pull_up_en=GPIO_PULLUP_DISABLE,
  405. .pull_down_en=GPIO_PULLDOWN_DISABLE,
  406. .intr_type=GPIO_INTR_DISABLE,
  407. };
  408. gpio_config(&gpiocfg);
  409. gpio_set_level(CONFIG_GC9A01_PIN_NUM_DC,0);
  410. #if(CONFIG_GC9A01_RESET_USED)
  411. gpiocfg.pin_bit_mask|=((uint64_t)1UL<<CONFIG_GC9A01_PIN_NUM_RST);
  412. gpio_config(&gpiocfg);
  413. gpio_set_level(CONFIG_GC9A01_PIN_NUM_RST,1);
  414. #endif
  415. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  416. #if(!CONFIG_GC9A01_CONTROL_BACK_LIGHT_MODE)
  417. gpiocfg.pin_bit_mask|=((uint64_t)1UL<<CONFIG_GC9A01_PIN_NUM_BCKL);
  418. gpio_config(&gpiocfg);
  419. gpio_set_level(CONFIG_GC9A01_PIN_NUM_BCKL,0);
  420. #endif
  421. #endif
  422. }
  423. void gc9a01_SPI_init(void)
  424. {
  425. esp_err_t ret;
  426. spi_bus_config_t buscfg={
  427. .mosi_io_num=CONFIG_GC9A01_PIN_NUM_MOSI,
  428. .miso_io_num=GPIO_NUM_NC,
  429. .sclk_io_num=CONFIG_GC9A01_PIN_NUM_SCK,
  430. .quadwp_io_num=-1,
  431. .quadhd_io_num=-1,
  432. .max_transfer_sz=250*250*2,
  433. };
  434. spi_device_interface_config_t devcfg={
  435. .clock_speed_hz=CONFIG_GC9A01_SPI_SCK_FREQ_M*1000*1000,
  436. .mode=0,
  437. .spics_io_num=CONFIG_GC9A01_PIN_NUM_CS,
  438. .queue_size=7,
  439. .pre_cb=lcd_spi_pre_transfer_callback,
  440. };
  441. ret=spi_bus_initialize(LCD_HOST,&buscfg,SPI_DMA_CH_AUTO);
  442. ESP_ERROR_CHECK(ret);
  443. ret=spi_bus_add_device(LCD_HOST,&devcfg,&spi);
  444. ESP_ERROR_CHECK(ret);
  445. }
  446. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  447. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_MODE)
  448. void LEDC_PWM_Duty_Set(uint8_t DutyP)
  449. {
  450. uint16_t Duty,MaxD;
  451. MaxD=(1<<(int)ledc_tConfig.duty_resolution)-1;
  452. if(DutyP>=100)Duty=MaxD;
  453. else
  454. {
  455. Duty=DutyP*(MaxD/(float)100);
  456. }
  457. ledc_cConfig.duty=Duty;
  458. ledc_channel_config(&ledc_cConfig);
  459. }
  460. void LEDC_Channel_Config(void)
  461. {
  462. ledc_cConfig.gpio_num=CONFIG_GC9A01_PIN_NUM_BCKL;
  463. ledc_cConfig.speed_mode=LEDC_LOW_SPEED_MODE;
  464. ledc_cConfig.channel=LEDC_CHANNEL_0;
  465. ledc_cConfig.intr_type=LEDC_INTR_DISABLE;
  466. ledc_cConfig.timer_sel=LEDC_TIMER_0;
  467. ledc_cConfig.duty=0;
  468. ledc_cConfig.hpoint=0;
  469. ledc_channel_config(&ledc_cConfig);
  470. }
  471. void LEDC_Timer_Config(void)
  472. {
  473. ledc_tConfig.speed_mode=LEDC_LOW_SPEED_MODE ;
  474. ledc_tConfig.duty_resolution=LEDC_TIMER_8_BIT;
  475. //ledc_tConfig.bit_num=LEDC_TIMER_8_BIT;
  476. ledc_tConfig.timer_num=LEDC_TIMER_0;
  477. ledc_tConfig.freq_hz=1000;
  478. ledc_tConfig.clk_cfg=LEDC_AUTO_CLK;
  479. ledc_timer_config(&ledc_tConfig);
  480. }
  481. #endif
  482. #endif
  483. void GC9A01_Init()
  484. {
  485. int cmd=0;
  486. GC9A01_X_Start = 0;
  487. GC9A01_Y_Start = 0;
  488. #if (CONFIG_GC9A01_BUFFER_MODE_PSRAM)
  489. if (ScreenBuff == NULL) {
  490. // ScreenBuffer has not yet been allocated
  491. ScreenBuff = heap_caps_malloc((GC9A01_Height * GC9A01_Width) * 2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT );
  492. }
  493. #endif
  494. gc9a01_GPIO_init();
  495. gc9a01_SPI_init();
  496. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  497. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_MODE)
  498. LEDC_Timer_Config();
  499. LEDC_Channel_Config();
  500. #endif
  501. #endif
  502. #if(CONFIG_GC9A01_RESET_USED)
  503. GC9A01_HardReset();
  504. #endif
  505. //Send all the commands
  506. while (lcd_init_cmds[cmd].databytes!=0xff)
  507. {
  508. lcd_cmd(lcd_init_cmds[cmd].cmd);
  509. lcd_data(lcd_init_cmds[cmd].data, lcd_init_cmds[cmd].databytes&0x1F);
  510. if (lcd_init_cmds[cmd].databytes&0x80)
  511. {
  512. delay_ms(100);
  513. }
  514. cmd++;
  515. }
  516. MemAccessModeSet(0,0,0,1);
  517. ColorModeSet(ColorMode_MCU_16bit);
  518. GC9A01_InversionMode(1);
  519. GC9A01_SleepMode(0);
  520. delay_ms(120);
  521. GC9A01_DisplayPower(1);
  522. delay_ms(20);
  523. #if(CONFIG_GC9A01_BUFFER_MODE)
  524. GC9A01_Clear();
  525. GC9A01_Update();
  526. delay_ms(30);
  527. #endif
  528. #if(CONFIG_GC9A01_CONTROL_BACK_LIGHT_USED)
  529. GC9A01_SetBL(100);
  530. #endif
  531. }
  532. #if(CONFIG_GC9A01_BUFFER_MODE)
  533. #if (CONFIG_GC9A01_BUFFER_MODE_PSRAM)
  534. void GC9A01_Free(void) {
  535. if (ScreenBuff != NULL) {
  536. free(ScreenBuff);
  537. }
  538. }
  539. #endif
  540. void GC9A01_Screen_Shot(uint16_t x,uint16_t y,uint16_t width ,uint16_t height,uint16_t * Buffer)
  541. {
  542. uint16_t i,j;
  543. for (i=0;i<height;i++)
  544. {
  545. for(j=0;j<width;j++)
  546. {
  547. #if(!CONFIG_GC9A01_BUFFER_SCREEN_FAST_MODE)
  548. Buffer[i*width+j]=GC9A01_GetPixel(x+j,y+i);
  549. #else
  550. Buffer[i*width+j]=ScreenBuff[((y+i) * GC9A01_Width )+ (x+j)];
  551. #endif
  552. }
  553. }
  554. }
  555. void GC9A01_Screen_Load(uint16_t x,uint16_t y,uint16_t width ,uint16_t height,uint16_t * Buffer)
  556. {
  557. uint16_t i,j;
  558. for (i=0;i<height;i++)
  559. {
  560. for(j=0;j<width;j++)
  561. {
  562. #if(!CONFIG_GC9A01_BUFFER_SCREEN_FAST_MODE)
  563. GC9A01_DrawPixel(x+j,y+i,Buffer[i*width+j]);
  564. #else
  565. ScreenBuff[((y+i) * GC9A01_Width )+ (x+j)] = Buffer[i*width+j];
  566. #endif
  567. }
  568. }
  569. }
  570. #endif