|
|
@@ -20,7 +20,7 @@
|
|
|
|
|
|
/*
|
|
|
This code displays some fancy graphics on the 320x240 LCD on an ESP-WROVER_KIT board.
|
|
|
- This example demonstrates the use of both spi_device_transmit as well as
|
|
|
+ This example demonstrates the use of both spi_device_transmit as well as
|
|
|
spi_device_queue_trans/spi_device_get_trans_result and pre-transmit callbacks.
|
|
|
|
|
|
Some info about the ILI9341/ST7789V: It has an C/D line, which is connected to a GPIO here. It expects this
|
|
|
@@ -38,7 +38,7 @@
|
|
|
#define PIN_NUM_RST 18
|
|
|
#define PIN_NUM_BCKL 5
|
|
|
|
|
|
-//To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use,
|
|
|
+//To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use,
|
|
|
//but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this.
|
|
|
#define PARALLEL_LINES 16
|
|
|
|
|
|
@@ -59,54 +59,101 @@ typedef enum {
|
|
|
|
|
|
//Place data into DRAM. Constant data gets placed into DROM by default, which is not accessible by DMA.
|
|
|
DRAM_ATTR static const lcd_init_cmd_t st_init_cmds[]={
|
|
|
+ /* Memory Data Access Control, MX=MV=1, MY=ML=MH=0, RGB=0 */
|
|
|
{0x36, {(1<<5)|(1<<6)}, 1},
|
|
|
+ /* Interface Pixel Format, 16bits/pixel for RGB/MCU interface */
|
|
|
{0x3A, {0x55}, 1},
|
|
|
+ /* Porch Setting */
|
|
|
{0xB2, {0x0c, 0x0c, 0x00, 0x33, 0x33}, 5},
|
|
|
+ /* Gate Control, Vgh=13.65V, Vgl=-10.43V */
|
|
|
{0xB7, {0x45}, 1},
|
|
|
+ /* VCOM Setting, VCOM=1.175V */
|
|
|
{0xBB, {0x2B}, 1},
|
|
|
+ /* LCM Control, XOR: BGR, MX, MH */
|
|
|
{0xC0, {0x2C}, 1},
|
|
|
+ /* VDV and VRH Command Enable, enable=1 */
|
|
|
{0xC2, {0x01, 0xff}, 2},
|
|
|
+ /* VRH Set, Vap=4.4+... */
|
|
|
{0xC3, {0x11}, 1},
|
|
|
+ /* VDV Set, VDV=0 */
|
|
|
{0xC4, {0x20}, 1},
|
|
|
+ /* Frame Rate Control, 60Hz, inversion=0 */
|
|
|
{0xC6, {0x0f}, 1},
|
|
|
+ /* Power Control 1, AVDD=6.8V, AVCL=-4.8V, VDDS=2.3V */
|
|
|
{0xD0, {0xA4, 0xA1}, 1},
|
|
|
+ /* Positive Voltage Gamma Control */
|
|
|
{0xE0, {0xD0, 0x00, 0x05, 0x0E, 0x15, 0x0D, 0x37, 0x43, 0x47, 0x09, 0x15, 0x12, 0x16, 0x19}, 14},
|
|
|
+ /* Negative Voltage Gamma Control */
|
|
|
{0xE1, {0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19}, 14},
|
|
|
+ /* Sleep Out */
|
|
|
{0x11, {0}, 0x80},
|
|
|
+ /* Display On */
|
|
|
{0x29, {0}, 0x80},
|
|
|
{0, {0}, 0xff}
|
|
|
};
|
|
|
|
|
|
DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds[]={
|
|
|
+ /* Power contorl B, power control = 0, DC_ENA = 1 */
|
|
|
{0xCF, {0x00, 0x83, 0X30}, 3},
|
|
|
+ /* Power on sequence control,
|
|
|
+ * cp1 keeps 1 frame, 1st frame enable
|
|
|
+ * vcl = 0, ddvdh=3, vgh=1, vgl=2
|
|
|
+ * DDVDH_ENH=1
|
|
|
+ */
|
|
|
{0xED, {0x64, 0x03, 0X12, 0X81}, 4},
|
|
|
+ /* Driver timing control A,
|
|
|
+ * non-overlap=default +1
|
|
|
+ * EQ=default - 1, CR=default
|
|
|
+ * pre-charge=default - 1
|
|
|
+ */
|
|
|
{0xE8, {0x85, 0x01, 0x79}, 3},
|
|
|
+ /* Power control A, Vcore=1.6V, DDVDH=5.6V */
|
|
|
{0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
|
|
|
+ /* Pump ratio control, DDVDH=2xVCl */
|
|
|
{0xF7, {0x20}, 1},
|
|
|
+ /* Driver timing control, all=0 unit */
|
|
|
{0xEA, {0x00, 0x00}, 2},
|
|
|
+ /* Power control 1, GVDD=4.75V */
|
|
|
{0xC0, {0x26}, 1},
|
|
|
+ /* Power control 2, DDVDH=VCl*2, VGH=VCl*7, VGL=-VCl*3 */
|
|
|
{0xC1, {0x11}, 1},
|
|
|
+ /* VCOM control 1, VCOMH=4.025V, VCOML=-0.950V */
|
|
|
{0xC5, {0x35, 0x3E}, 2},
|
|
|
+ /* VCOM control 2, VCOMH=VMH-2, VCOML=VML-2 */
|
|
|
{0xC7, {0xBE}, 1},
|
|
|
+ /* Memory access contorl, MX=MY=0, MV=1, ML=0, BGR=1, MH=0 */
|
|
|
{0x36, {0x28}, 1},
|
|
|
+ /* Pixel format, 16bits/pixel for RGB/MCU interface */
|
|
|
{0x3A, {0x55}, 1},
|
|
|
+ /* Frame rate control, f=fosc, 70Hz fps */
|
|
|
{0xB1, {0x00, 0x1B}, 2},
|
|
|
+ /* Enable 3G, disabled */
|
|
|
{0xF2, {0x08}, 1},
|
|
|
+ /* Gamma set, curve 1 */
|
|
|
{0x26, {0x01}, 1},
|
|
|
+ /* Positive gamma correction */
|
|
|
{0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15},
|
|
|
+ /* Negative gamma correction */
|
|
|
{0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15},
|
|
|
+ /* Column address set, SC=0, EC=0xEF */
|
|
|
{0x2A, {0x00, 0x00, 0x00, 0xEF}, 4},
|
|
|
- {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4},
|
|
|
+ /* Page address set, SP=0, EP=0x013F */
|
|
|
+ {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4},
|
|
|
+ /* Memory write */
|
|
|
{0x2C, {0}, 0},
|
|
|
+ /* Entry mode set, Low vol detect disabled, normal display */
|
|
|
{0xB7, {0x07}, 1},
|
|
|
+ /* Display function control */
|
|
|
{0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
|
|
|
+ /* Sleep out */
|
|
|
{0x11, {0}, 0x80},
|
|
|
+ /* Display on */
|
|
|
{0x29, {0}, 0x80},
|
|
|
{0, {0}, 0xff},
|
|
|
};
|
|
|
|
|
|
//Send a command to the LCD. Uses spi_device_transmit, which waits until the transfer is complete.
|
|
|
-void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
|
|
|
+void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
|
|
|
{
|
|
|
esp_err_t ret;
|
|
|
spi_transaction_t t;
|
|
|
@@ -119,7 +166,7 @@ void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
|
|
|
}
|
|
|
|
|
|
//Send data to the LCD. Uses spi_device_transmit, which waits until the transfer is complete.
|
|
|
-void lcd_data(spi_device_handle_t spi, const uint8_t *data, int len)
|
|
|
+void lcd_data(spi_device_handle_t spi, const uint8_t *data, int len)
|
|
|
{
|
|
|
esp_err_t ret;
|
|
|
spi_transaction_t t;
|
|
|
@@ -134,13 +181,13 @@ void lcd_data(spi_device_handle_t spi, const uint8_t *data, int len)
|
|
|
|
|
|
//This function is called (in irq context!) just before a transmission starts. It will
|
|
|
//set the D/C line to the value indicated in the user field.
|
|
|
-void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
|
|
|
+void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
|
|
|
{
|
|
|
int dc=(int)t->user;
|
|
|
gpio_set_level(PIN_NUM_DC, dc);
|
|
|
}
|
|
|
|
|
|
-uint32_t lcd_get_id(spi_device_handle_t spi)
|
|
|
+uint32_t lcd_get_id(spi_device_handle_t spi)
|
|
|
{
|
|
|
//get_id cmd
|
|
|
lcd_cmd( spi, 0x04);
|
|
|
@@ -158,7 +205,7 @@ uint32_t lcd_get_id(spi_device_handle_t spi)
|
|
|
}
|
|
|
|
|
|
//Initialize the display
|
|
|
-void lcd_init(spi_device_handle_t spi)
|
|
|
+void lcd_init(spi_device_handle_t spi)
|
|
|
{
|
|
|
int cmd=0;
|
|
|
const lcd_init_cmd_t* lcd_init_cmds;
|
|
|
@@ -226,7 +273,7 @@ void lcd_init(spi_device_handle_t spi)
|
|
|
//before sending the line data itself; a total of 6 transactions. (We can't put all of this in just one transaction
|
|
|
//because the D/C line needs to be toggled in the middle.)
|
|
|
//This routine queues these commands up so they get sent as quickly as possible.
|
|
|
-static void send_lines(spi_device_handle_t spi, int ypos, uint16_t *linedata)
|
|
|
+static void send_lines(spi_device_handle_t spi, int ypos, uint16_t *linedata)
|
|
|
{
|
|
|
esp_err_t ret;
|
|
|
int x;
|
|
|
@@ -277,7 +324,7 @@ static void send_lines(spi_device_handle_t spi, int ypos, uint16_t *linedata)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void send_line_finish(spi_device_handle_t spi)
|
|
|
+static void send_line_finish(spi_device_handle_t spi)
|
|
|
{
|
|
|
spi_transaction_t *rtrans;
|
|
|
esp_err_t ret;
|
|
|
@@ -291,9 +338,9 @@ static void send_line_finish(spi_device_handle_t spi)
|
|
|
|
|
|
|
|
|
//Simple routine to generate some patterns and send them to the LCD. Don't expect anything too
|
|
|
-//impressive. Because the SPI driver handles transactions in the background, we can calculate the next line
|
|
|
+//impressive. Because the SPI driver handles transactions in the background, we can calculate the next line
|
|
|
//while the previous one is being sent.
|
|
|
-static void display_pretty_colors(spi_device_handle_t spi)
|
|
|
+static void display_pretty_colors(spi_device_handle_t spi)
|
|
|
{
|
|
|
uint16_t *lines[2];
|
|
|
//Allocate memory for the pixel buffers
|
|
|
@@ -305,7 +352,7 @@ static void display_pretty_colors(spi_device_handle_t spi)
|
|
|
//Indexes of the line currently being sent to the LCD and the line we're calculating.
|
|
|
int sending_line=-1;
|
|
|
int calc_line=0;
|
|
|
-
|
|
|
+
|
|
|
while(1) {
|
|
|
frame++;
|
|
|
for (int y=0; y<240; y+=PARALLEL_LINES) {
|