example(spi_master): add descriptions about LCD example

This commit is contained in:
Michael (XIAO Xufeng) 2018-04-18 14:36:26 +08:00 committed by michael
parent 1e8ab3d18e
commit dd91152589

View file

@ -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) {