30
30
before the transaction is sent, the callback will set this line to the correct state.
31
31
*/
32
32
33
+ #define TDISPLAY
34
+
35
+ #ifdef TDISPLAY
33
36
#define PIN_NUM_MISO 17
34
37
#define PIN_NUM_MOSI 19
35
38
#define PIN_NUM_CLK 18
36
39
#define PIN_NUM_CS 5
37
40
38
41
#define PIN_NUM_DC 16
39
42
#define PIN_NUM_RST 20
43
+ #define LINE_LEN 136
44
+
45
+ #else
46
+
47
+ #define PIN_NUM_MISO 12
48
+ #define PIN_NUM_MOSI 23
49
+ #define PIN_NUM_CLK 18
50
+ #define PIN_NUM_CS 27
51
+
52
+ #define PIN_NUM_DC 32
53
+ #define PIN_NUM_RST 05
54
+
55
+ #define LINE_LEN 240
56
+ #endif
57
+
40
58
#define PIN_NUM_BCKL 4
41
59
42
60
//To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use,
43
61
//but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this.
44
- #define PARALLEL_LINES 24 // must divide into 240...
45
- #define LINE_LEN 136
62
+ #define PARALLEL_LINES 20 // must divide into 240 and 320
46
63
47
64
static spi_device_handle_t ili_spi ;
48
65
static uint16_t * dma_lines [2 ];
66
+ static uint8_t backlight = 0 ;
49
67
50
68
/*
51
69
The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct.
@@ -56,48 +74,6 @@ typedef struct {
56
74
uint8_t databytes ; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
57
75
} lcd_init_cmd_t ;
58
76
59
- typedef enum {
60
- LCD_TYPE_ILI = 1 ,
61
- LCD_TYPE_ST ,
62
- LCD_TYPE_MAX ,
63
- } type_lcd_t ;
64
-
65
- //Place data into DRAM. Constant data gets placed into DROM by default, which is not accessible by DMA.
66
- DRAM_ATTR static const lcd_init_cmd_t st_init_cmds []= {
67
- /* Memory Data Access Control, MX=MV=1, MY=ML=MH=0, RGB=0 */
68
- {0x36 , {(1 <<5 )|(1 <<6 )}, 1 },
69
- /* Interface Pixel Format, 16bits/pixel for RGB/MCU interface */
70
- // {0x3A, {0x55}, 1},
71
- {0x3A , {0x66 }, 1 },
72
- /* Porch Setting */
73
- {0xB2 , {0x0c , 0x0c , 0x00 , 0x33 , 0x33 }, 5 },
74
- /* Gate Control, Vgh=13.65V, Vgl=-10.43V */
75
- {0xB7 , {0x45 }, 1 },
76
- /* VCOM Setting, VCOM=1.175V */
77
- {0xBB , {0x2B }, 1 },
78
- /* LCM Control, XOR: BGR, MX, MH */
79
- {0xC0 , {0x2C }, 1 },
80
- /* VDV and VRH Command Enable, enable=1 */
81
- {0xC2 , {0x01 , 0xff }, 2 },
82
- /* VRH Set, Vap=4.4+... */
83
- {0xC3 , {0x11 }, 1 },
84
- /* VDV Set, VDV=0 */
85
- {0xC4 , {0x20 }, 1 },
86
- /* Frame Rate Control, 60Hz, inversion=0 */
87
- {0xC6 , {0x0f }, 1 },
88
- /* Power Control 1, AVDD=6.8V, AVCL=-4.8V, VDDS=2.3V */
89
- {0xD0 , {0xA4 , 0xA1 }, 1 },
90
- /* Positive Voltage Gamma Control */
91
- {0xE0 , {0xD0 , 0x00 , 0x05 , 0x0E , 0x15 , 0x0D , 0x37 , 0x43 , 0x47 , 0x09 , 0x15 , 0x12 , 0x16 , 0x19 }, 14 },
92
- /* Negative Voltage Gamma Control */
93
- {0xE1 , {0xD0 , 0x00 , 0x05 , 0x0D , 0x0C , 0x06 , 0x2D , 0x44 , 0x40 , 0x0E , 0x1C , 0x18 , 0x16 , 0x19 }, 14 },
94
- /* Sleep Out */
95
- {0x11 , {0 }, 0x80 },
96
- /* Display On */
97
- {0x29 , {0 }, 0x80 },
98
- {0 , {0 }, 0xff }
99
- };
100
-
101
77
#if 0
102
78
DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds []= {
103
79
/* Power contorl B, power control = 0, DC_ENA = 1 */
@@ -158,24 +134,63 @@ DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds[]={
158
134
{0x29 , {0 }, 0x80 },
159
135
{0 , {0 }, 0xff },
160
136
};
137
+ #elif 1
138
+ DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds []= {
139
+ // {0x01, {0}, 0}, // software reset
140
+ {0xCB , {0x39 , 0x2C , 0x00 , 0x34 , 0x02 }, 5 },
141
+ {0xCF , {0x00 , 0X83 , 0X30 }, 3 },
142
+ // {0xEF, {0x03, 0x80, 0x02}, 3},
143
+ {0xE8 , {0x84 , 0x11 , 0x7a }, 3 },
144
+ {0xEA , {0x00 , 0x00 }, 2 },
145
+ {0xED , {0x64 , 0x03 , 0X12 , 0X81 }, 4 },
146
+ {0xF7 , {0x30 }, 1 },
147
+ {0xC0 , {0x29 }, 1 }, //Power control VRH[5:0]
148
+ {0xC1 , {0x00 }, 1 }, //Power control SAP[2:0];BT[3:0]
149
+ {0xC5 , {0x31 , 0x08 }, 2 }, //VCM control
150
+ {0xC7 , {0xC0 }, 1 }, //VCM control2
151
+ #ifdef TDISPLAY
152
+ {0x36 , {0xC8 }, 1 },
153
+ {0x21 , {0 }, 0 }, // invert on
154
+ #else
155
+ {0x36 , {0x48 }, 1 },
156
+ {0x20 , {0 }, 0 }, // invert off
157
+ #endif
158
+ {0x3A , {0x55 }, 1 }, // *** INTERFACE PIXEL FORMAT: 0x66 -> 18 bit; 0x55 -> 16 bit
159
+ {0xB1 , {0x00 , 0x1B }, 2 },
160
+ {0xB6 , {0x08 , 0x82 , 0x27 , 0x00 }, 4 }, // Display Function Control
161
+ // {0x30, {0x00, 0x00, 0x01, 0x3F}, 4},
162
+ {0xF2 , {0x02 }, 1 }, // 3Gamma Function: Disable (0x02), Enable (0x03)
163
+ {0xE0 , {0x1F , 0x1A , 0x18 , 0x0A , 0x0F , 0x06 , 0x45 , 0X87 , 0x32 , 0x0A , 0x07 , 0x02 , 0x07 , 0x05 , 0x00 }, 15 },
164
+ {0xE1 , {0x00 , 0x25 , 0x27 , 0x05 , 0x10 , 0x09 , 0x3A , 0x78 , 0x4D , 0x05 , 0x18 , 0x0D , 0x38 , 0x3A , 0x1F }, 15 },
165
+ // {0x26, {0x08}, 1}, //Gamma curve selected (0x01, 0x02, 0x04, 0x08)
166
+ // {0xE0, { 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00}, 15}, //Positive Gamma Correction
167
+ // {0xE1, { 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F}, 15},
168
+ {0x11 , {0 }, 0x80 }, // Sleep out
169
+ {0x29 , {0 }, 0x80 }, // Display on
170
+ {0 , {0 }, 0xff }
171
+ };
161
172
#else
162
173
DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds []= {
163
174
// {0x01, {0}, 0}, // software reset
175
+ {0x20 , {0 }, 0 }, // invert off
164
176
{0xCB , {0x39 , 0x2C , 0x00 , 0x34 , 0x02 }, 5 },
165
- {0xCF , {0x00 , 0XC1 , 0X30 }, 3 },
177
+ {0xCF , {0x00 , 0xC1 , 0x30 }, 3 },
166
178
{0xEF , {0x03 , 0x80 , 0x02 }, 3 },
167
179
{0xE8 , {0x85 , 0x00 , 0x78 }, 3 },
168
180
{0xEA , {0x00 , 0x00 }, 2 },
169
- {0xED , {0x64 , 0x03 , 0X12 , 0X81 }, 4 },
181
+ {0xED , {0x64 , 0x03 , 0x12 , 0x81 }, 4 },
170
182
{0xF7 , {0x20 }, 1 },
171
183
{0xC0 , {0x23 }, 1 }, //Power control VRH[5:0]
172
184
{0xC1 , {0x10 }, 1 }, //Power control SAP[2:0];BT[3:0]
173
185
{0xC5 , {0x3e , 0x28 }, 2 }, //VCM control
174
186
{0xC7 , {0x86 }, 1 }, //VCM control2
187
+ #ifdef TDISPLAY
175
188
{0x36 , {0x28 }, 1 },
189
+ #else
190
+ {0x36 , {0x48 }, 1 },
191
+ #endif
176
192
{0x3A , {0x55 }, 1 }, // *** INTERFACE PIXEL FORMAT: 0x66 -> 18 bit; 0x55 -> 16 bit
177
- {0x20 , {0 }, 0 }, // invert off
178
- {0xB1 , {0x00 , 0x1B }, 2 },
193
+ {0xB1 , {0x03 , 0x1f }, 2 },
179
194
{0xB6 , {0x08 , 0x82 , 0x27 , 0x00 }, 4 }, // Display Function Control
180
195
// {0x30, {0x00, 0x00, 0x01, 0x3F}, 4},
181
196
// {0xF2, {0x00}, 1}, // 3Gamma Function: Disable (0x02), Enable (0x03)
@@ -186,9 +201,6 @@ DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds[]={
186
201
{0x29 , {0 }, 0x80 }, // Display on
187
202
{0 , {0 }, 0xff }
188
203
};
189
-
190
-
191
-
192
204
#endif
193
205
194
206
/* Send a command to the LCD. Uses spi_device_polling_transmit, which waits
@@ -263,52 +275,23 @@ static void lcd_init()
263
275
int cmd = 0 ;
264
276
const lcd_init_cmd_t * lcd_init_cmds ;
265
277
266
- //Initialize non-SPI GPIOs
267
- gpio_set_direction (PIN_NUM_DC , GPIO_MODE_OUTPUT );
268
- gpio_set_direction (PIN_NUM_RST , GPIO_MODE_OUTPUT );
269
- gpio_set_direction (PIN_NUM_BCKL , GPIO_MODE_OUTPUT );
270
278
271
279
//Reset the display
272
280
gpio_set_level (PIN_NUM_RST , 0 );
273
- vTaskDelay (100 / portTICK_RATE_MS );
281
+ vTaskDelay (50 / portTICK_RATE_MS );
274
282
gpio_set_level (PIN_NUM_RST , 1 );
275
- vTaskDelay (100 / portTICK_RATE_MS );
283
+ vTaskDelay (50 / portTICK_RATE_MS );
276
284
285
+ lcd_cmd (TFT_CMD_SWRESET );
286
+ vTaskDelay (10 / portTICK_RATE_MS );
277
287
lcd_cmd (TFT_CMD_SWRESET );
278
288
279
289
//detect LCD type
280
290
uint32_t lcd_id = lcd_get_id (ili_spi );
281
291
int lcd_detected_type = 0 ;
282
292
int lcd_type ;
283
293
284
- printf ("LCD ID: %08X\n" , lcd_id );
285
- if ( lcd_id == 0 ) {
286
- //zero, ili
287
- lcd_detected_type = LCD_TYPE_ILI ;
288
- printf ("ILI9341 detected.\n" );
289
- } else {
290
- // none-zero, ST
291
- lcd_detected_type = LCD_TYPE_ST ;
292
- printf ("ST7789V detected.\n" );
293
- }
294
-
295
- lcd_type = lcd_detected_type ;
296
- #ifdef CONFIG_LCD_TYPE_AUTO
297
-
298
- #elif defined( CONFIG_LCD_TYPE_ST7789V )
299
- printf ("kconfig: force CONFIG_LCD_TYPE_ST7789V.\n" );
300
- lcd_type = LCD_TYPE_ST ;
301
- #elif defined( CONFIG_LCD_TYPE_ILI9341 )
302
- printf ("kconfig: force CONFIG_LCD_TYPE_ILI9341.\n" );
303
- lcd_type = LCD_TYPE_ILI ;
304
- #endif
305
- if ( lcd_type == LCD_TYPE_ST ) {
306
- printf ("LCD ST7789V initialization.\n" );
307
- lcd_init_cmds = st_init_cmds ;
308
- } else {
309
- printf ("LCD ILI9341 initialization.\n" );
310
- lcd_init_cmds = ili_init_cmds ;
311
- }
294
+ lcd_init_cmds = ili_init_cmds ;
312
295
313
296
//Send all the commands
314
297
while (lcd_init_cmds [cmd ].databytes != 0xff ) {
@@ -319,9 +302,6 @@ static void lcd_init()
319
302
}
320
303
cmd ++ ;
321
304
}
322
-
323
- ///Enable backlight
324
- gpio_set_level (PIN_NUM_BCKL , 1 );
325
305
}
326
306
327
307
@@ -369,12 +349,18 @@ static void send_lines(int ypos, int line)
369
349
}
370
350
trans [x ].flags = SPI_TRANS_USE_TXDATA ;
371
351
}
372
- ypos += 41 ;
352
+ #ifdef TDISPLAY
353
+ const int sx = 52 , sy = 41 ;
354
+ #else
355
+ const int sx = 0 , sy = 1 ;
356
+ #endif
357
+
358
+ ypos += sy ;
373
359
trans [0 ].tx_data [0 ]= 0x2A ; //Column Address Set
374
360
trans [1 ].tx_data [0 ]= 0 ; //Start Col High
375
- trans [1 ].tx_data [1 ]= 52 ; //Start Col Low
376
- trans [1 ].tx_data [2 ]= (52 + LINE_LEN - 1 )>>8 ; //End Col High
377
- trans [1 ].tx_data [3 ]= (52 + LINE_LEN - 1 )& 0xff ; //End Col Low
361
+ trans [1 ].tx_data [1 ]= sx ; //Start Col Low
362
+ trans [1 ].tx_data [2 ]= (sx + LINE_LEN - 1 )>>8 ; //End Col High
363
+ trans [1 ].tx_data [3 ]= (sx + LINE_LEN - 1 )& 0xff ; //End Col Low
378
364
trans [2 ].tx_data [0 ]= 0x2B ; //Page address set
379
365
trans [3 ].tx_data [0 ]= ypos >>8 ; //Start page high
380
366
trans [3 ].tx_data [1 ]= ypos & 0xff ; //start page low
@@ -411,7 +397,7 @@ static void lcd_setup() {
411
397
.max_transfer_sz = PARALLEL_LINES * LINE_LEN * 2 + 8
412
398
};
413
399
spi_device_interface_config_t devcfg = {
414
- .clock_speed_hz = 10 * 1000 * 1000 , //Clock out at 10 MHz
400
+ .clock_speed_hz = 20 * 1000 * 1000 , //Clock out at 10 MHz
415
401
.mode = 0 , //SPI mode 0
416
402
.spics_io_num = PIN_NUM_CS , //CS pin
417
403
.queue_size = 5 , //We want to be able to queue 7 transactions at a time
@@ -423,53 +409,98 @@ static void lcd_setup() {
423
409
//Attach the LCD to the SPI bus
424
410
ret = spi_bus_add_device (HSPI_HOST , & devcfg , & ili_spi );
425
411
ESP_ERROR_CHECK (ret );
426
- //Initialize the LCD
427
- lcd_init (ili_spi );
428
412
//Allocate memory for the pixel buffers
429
413
for (int i = 0 ; i < 2 ; i ++ ) {
430
414
dma_lines [i ]= heap_caps_malloc (LINE_LEN * PARALLEL_LINES * sizeof (uint16_t ), MALLOC_CAP_DMA );
431
415
memset (dma_lines [i ], 0 , LINE_LEN * PARALLEL_LINES * sizeof (uint16_t ));
432
416
}
417
+
418
+ //Initialize non-SPI GPIOs
419
+ gpio_set_direction (PIN_NUM_DC , GPIO_MODE_OUTPUT );
420
+ gpio_set_direction (PIN_NUM_RST , GPIO_MODE_OUTPUT );
421
+ gpio_set_direction (PIN_NUM_BCKL , GPIO_MODE_OUTPUT );
422
+
423
+ ///Disable backlight
424
+ gpio_set_level (PIN_NUM_BCKL , 0 );
433
425
}
434
426
435
- static uint8_t minc (uint32_t c ) {
427
+ static uint8_t minc (int32_t c ) {
436
428
if (c > 255 )
429
+ return 255 ;
430
+ return c ;
431
+ }
432
+
433
+ static uint8_t nn (int32_t c )
434
+ {
435
+ if (c < 0 )
437
436
return 0 ;
438
- return 255 - c ;
437
+ return c ;
439
438
}
440
439
441
- void ili_refresh (int contrast , int hue , int width , int height , char * data )
440
+
441
+ void ili_refresh (int contrast , int hue , int bl , int width , int height , char * data )
442
442
{
443
- static int initialized ;
444
- if (!initialized ) {
443
+ static int setup , initialized ;
444
+ if (!setup ) {
445
445
lcd_setup ();
446
+ setup = 1 ;
447
+ }
448
+
449
+ if (bl != backlight ) {
450
+ backlight = !!bl ;
451
+ ///Enable backlight
452
+ gpio_set_level (PIN_NUM_BCKL , backlight );
453
+ if (!backlight ) {
454
+ lcd_cmd (TFT_CMD_SWRESET );
455
+ initialized = 0 ;
456
+ }
457
+ }
458
+
459
+ if (!backlight ) {
460
+ initialized = 0 ;
461
+ return ;
462
+ }
463
+
464
+ if (!initialized ) {
465
+ lcd_init ();
446
466
initialized = 1 ;
447
467
}
448
468
469
+ #if 1
470
+ lcd_cmd (0x36 );
471
+ uint8_t d [1 ] = {0xC8 };
472
+ lcd_data (d , 1 );
473
+ #endif
474
+
449
475
// rebuild palette if needed
450
476
static int last_contrast = -1 , last_hue = -1 ;
451
477
static uint16_t palette [256 ];
478
+ contrast = 100 ;
452
479
if (contrast != last_contrast || hue != last_hue ) {
453
- uint32_t c = contrast , h = hue ;
454
- uint32_t r , g , b ;
480
+ last_contrast = contrast ;
481
+ last_hue = hue ;
482
+ int32_t c = contrast , h = hue ;
483
+ int32_t r , g , b ;
455
484
if (h < 85 ) {
456
- r = 85 - h ;
457
- g = 85 - r ;
458
- b = 0 ;
485
+ r = 85 ;
486
+ g = nn ( 2 * h - 85 ) ;
487
+ b = nn ( 85 - 2 * h ) ;
459
488
} else if (h < 170 ) {
460
- r = 0 ;
461
- g = 170 - h ;
462
- b = 85 - g ;
489
+ r = nn ( 85 - 2 * ( h - 85 )) ;
490
+ g = 85 ;
491
+ b = nn ( 2 * ( h - 85 ) - 85 ) ;
463
492
} else {
464
- g = 0 ;
465
- b = 255 - h ;
466
- r = 85 - b ;
493
+ r = nn ( 2 * ( h - 170 ) - 85 ) ;
494
+ g = nn ( 85 - 2 * ( h - 170 )) ;
495
+ b = 85 ;
467
496
}
497
+
468
498
for (uint32_t i = 0 ; i < 256 ; i ++ ) {
469
499
uint32_t red = minc (i * c * r /8500 );
470
500
uint32_t green = minc (i * c * g /8500 );
471
501
uint32_t blue = minc (i * c * b /8500 );
472
502
503
+
473
504
uint16_t c = ((red & 0xF8 )<<8 ) | ((green & 0xFC ) << 3 ) | ((blue & 0xF8 )>>3 );
474
505
uint8_t * v = (uint8_t * )& c ;
475
506
palette [i ] = (v [0 ]<<8 ) | v [1 ];
0 commit comments