-
-
Save CodeZombie/385ad82980c6f7b5c169ee7d86185a37 to your computer and use it in GitHub Desktop.
| #include "esp_lcd_panel_io.h" | |
| #include "esp_lcd_panel_vendor.h" | |
| #include "esp_lcd_panel_ops.h" | |
| #include "esp_lcd_ili9341.h" | |
| #define SPI_HOST SPI2_HOST // FSPI on S2 | |
| esp_lcd_panel_handle_t panel_handle; | |
| void initialize_ili9341() { | |
| spi_bus_config_t buscfg = { | |
| .miso_io_num = -1, | |
| .mosi_io_num = PIN_MOSI, | |
| .sclk_io_num = PIN_SCK, | |
| .quadwp_io_num = -1, | |
| .quadhd_io_num = -1, | |
| .max_transfer_sz = SCREEN_WIDTH * 10 * sizeof(uint16_t) | |
| }; | |
| ESP_ERROR_CHECK(spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); | |
| esp_lcd_panel_io_handle_t io_handle = NULL; | |
| esp_lcd_panel_io_spi_config_t io_config = { | |
| .dc_gpio_num = PIN_DC, | |
| .cs_gpio_num = PIN_CS, | |
| .pclk_hz = 40 * 1000 * 1000, // 40MHz | |
| .lcd_cmd_bits = 8, | |
| .lcd_param_bits = 8, | |
| .spi_mode = 0, | |
| .trans_queue_depth = 10, | |
| }; | |
| ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI_HOST, &io_config, &io_handle)); | |
| esp_lcd_panel_dev_config_t panel_config = { | |
| .reset_gpio_num = PIN_RST, | |
| .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, | |
| .bits_per_pixel = 16, | |
| }; | |
| ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(io_handle, &panel_config, &panel_handle)); | |
| ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); | |
| ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); | |
| ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false)); | |
| ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); | |
| ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); | |
| } |
I think the ESP_LCD library sets up DMA for you in the background, so I don't think there's much SPI polling going on (beyond the necessary PASET and CASET, which what minimal docs exist claim are done via polling), but I haven't actually confirmed that the pixel transfer is done via DMA, but it appears that that is the case.
Okay, yeah link confirms that cmds are sent via polling, so that confirms that this library isn't doing any more hardware acceleration beyond what you could already accomplish with the standard esp SPI library. So if you use this, you're just paying for the library's overhead for no gain.
I'd recommend just setting the driver up manually and handling DMA yourself. I care deeply about optimization with microcontroller display drivers, and using ESP_LCD just makes optimization harder.
plus it does runtime checks on your esp_lcd_panel_draw_bitmap calls (checks to see if start_x is less than end_x, etc) so that's just unnecessary overhead for nothin'. You should be ensuring that situation can't happen before you even think about sending a buffer to SPI, so that's really an unnecessary couple of cycles for no gain (unless you're writing bad code).
Leaving this here in case it's useful for someone in the future.
There only seems to be one example of the ili9341 startup routine using ESP-IDF's ESP_LCD library anywhere online, and it's very hard to read. Here's a real simple example.
After you get this working, you can blit to the screen with
esp_lcd_panel_draw_bitmap(panel_handle, x, y, x + w, y + h, color_buffer);