From dd911525891a1a42dff75091f25d297ef8fe3ce7 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Wed, 18 Apr 2018 14:36:26 +0800 Subject: [PATCH] example(spi_master): add descriptions about LCD example --- .../spi_master/main/spi_master_example_main.c | 73 +++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/examples/peripherals/spi_master/main/spi_master_example_main.c b/examples/peripherals/spi_master/main/spi_master_example_main.c index 77bfe5fa9..8b55fe268 100644 --- a/examples/peripherals/spi_master/main/spi_master_example_main.c +++ b/examples/peripherals/spi_master/main/spi_master_example_main.c @@ -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) {