mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 06:11:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			180 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: CC0-1.0
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include "sdkconfig.h"
 | 
						|
#include "freertos/FreeRTOS.h"
 | 
						|
#include "freertos/task.h"
 | 
						|
#include "esp_lcd_panel_io.h"
 | 
						|
#include "esp_lcd_panel_vendor.h"
 | 
						|
#include "esp_lcd_panel_ops.h"
 | 
						|
#include "esp_heap_caps.h"
 | 
						|
#include "driver/spi_master.h"
 | 
						|
#include "driver/gpio.h"
 | 
						|
#include "pretty_effect.h"
 | 
						|
 | 
						|
// Using SPI2 in the example, as it also supports octal modes on some targets
 | 
						|
#define LCD_HOST       SPI2_HOST
 | 
						|
// 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 CONFIG_EXAMPLE_LCD_FLUSH_PARALLEL_LINES
 | 
						|
// The number of frames to show before rotate the graph
 | 
						|
#define ROTATE_FRAME   30
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000)
 | 
						|
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL  0
 | 
						|
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL
 | 
						|
#define EXAMPLE_PIN_NUM_DATA0          23  /*!< for 1-line SPI, this also refereed as MOSI */
 | 
						|
#define EXAMPLE_PIN_NUM_PCLK           19
 | 
						|
#define EXAMPLE_PIN_NUM_CS             22
 | 
						|
#define EXAMPLE_PIN_NUM_DC             21
 | 
						|
#define EXAMPLE_PIN_NUM_RST            18
 | 
						|
#define EXAMPLE_PIN_NUM_BK_LIGHT       5
 | 
						|
 | 
						|
// The pixel number in horizontal and vertical
 | 
						|
#define EXAMPLE_LCD_H_RES              320
 | 
						|
#define EXAMPLE_LCD_V_RES              240
 | 
						|
// Bit number used to represent command and parameter
 | 
						|
#define EXAMPLE_LCD_CMD_BITS           8
 | 
						|
#define EXAMPLE_LCD_PARAM_BITS         8
 | 
						|
 | 
						|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
 | 
						|
#define EXAMPLE_PIN_NUM_DATA1    7
 | 
						|
#define EXAMPLE_PIN_NUM_DATA2    8
 | 
						|
#define EXAMPLE_PIN_NUM_DATA3    9
 | 
						|
#define EXAMPLE_PIN_NUM_DATA4    10
 | 
						|
#define EXAMPLE_PIN_NUM_DATA5    11
 | 
						|
#define EXAMPLE_PIN_NUM_DATA6    12
 | 
						|
#define EXAMPLE_PIN_NUM_DATA7    13
 | 
						|
#endif // CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
 | 
						|
 | 
						|
// Simple routine to generate some patterns and send them to the LCD. Because the
 | 
						|
// SPI driver handles transactions in the background, we can calculate the next line
 | 
						|
// while the previous one is being sent.
 | 
						|
static uint16_t *s_lines[2];
 | 
						|
static void display_pretty_colors(esp_lcd_panel_handle_t panel_handle)
 | 
						|
{
 | 
						|
    int frame = 0;
 | 
						|
    // Indexes of the line currently being sent to the LCD and the line we're calculating
 | 
						|
    int sending_line = 0;
 | 
						|
    int calc_line = 0;
 | 
						|
 | 
						|
    // After ROTATE_FRAME frames, the image will be rotated
 | 
						|
    while (frame <= ROTATE_FRAME) {
 | 
						|
        frame++;
 | 
						|
        for (int y = 0; y < EXAMPLE_LCD_V_RES; y += PARALLEL_LINES) {
 | 
						|
            // Calculate a line
 | 
						|
            pretty_effect_calc_lines(s_lines[calc_line], y, frame, PARALLEL_LINES);
 | 
						|
            sending_line = calc_line;
 | 
						|
            calc_line = !calc_line;
 | 
						|
            // Send the calculated data
 | 
						|
            esp_lcd_panel_draw_bitmap(panel_handle, 0, y, 0 + EXAMPLE_LCD_H_RES, y + PARALLEL_LINES, s_lines[sending_line]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void app_main(void)
 | 
						|
{
 | 
						|
    gpio_config_t bk_gpio_config = {
 | 
						|
        .mode = GPIO_MODE_OUTPUT,
 | 
						|
        .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT
 | 
						|
    };
 | 
						|
    // Initialize the GPIO of backlight
 | 
						|
    ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
 | 
						|
 | 
						|
    spi_bus_config_t buscfg = {
 | 
						|
        .sclk_io_num = EXAMPLE_PIN_NUM_PCLK,
 | 
						|
        .mosi_io_num = EXAMPLE_PIN_NUM_DATA0,
 | 
						|
        .miso_io_num = -1,
 | 
						|
        .quadwp_io_num = -1,
 | 
						|
        .quadhd_io_num = -1,
 | 
						|
        .max_transfer_sz = PARALLEL_LINES * EXAMPLE_LCD_H_RES * 2 + 8
 | 
						|
    };
 | 
						|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
 | 
						|
    buscfg.data1_io_num = EXAMPLE_PIN_NUM_DATA1;
 | 
						|
    buscfg.data2_io_num = EXAMPLE_PIN_NUM_DATA2;
 | 
						|
    buscfg.data3_io_num = EXAMPLE_PIN_NUM_DATA3;
 | 
						|
    buscfg.data4_io_num = EXAMPLE_PIN_NUM_DATA4;
 | 
						|
    buscfg.data5_io_num = EXAMPLE_PIN_NUM_DATA5;
 | 
						|
    buscfg.data6_io_num = EXAMPLE_PIN_NUM_DATA6;
 | 
						|
    buscfg.data7_io_num = EXAMPLE_PIN_NUM_DATA7;
 | 
						|
    buscfg.flags = SPICOMMON_BUSFLAG_OCTAL;
 | 
						|
#endif
 | 
						|
    // Initialize the SPI bus
 | 
						|
    ESP_ERROR_CHECK(spi_bus_initialize(LCD_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 = EXAMPLE_PIN_NUM_DC,
 | 
						|
        .cs_gpio_num = EXAMPLE_PIN_NUM_CS,
 | 
						|
        .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
 | 
						|
        .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
 | 
						|
        .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
 | 
						|
        .spi_mode = 0,
 | 
						|
        .trans_queue_depth = 10,
 | 
						|
    };
 | 
						|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
 | 
						|
    io_config.spi_mode = 3;  // using mode 3 to simulate Intel 8080 timing
 | 
						|
    io_config.flags.octal_mode = 1;
 | 
						|
#endif
 | 
						|
    // Attach the LCD to the SPI bus
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));
 | 
						|
 | 
						|
    esp_lcd_panel_handle_t panel_handle = NULL;
 | 
						|
    esp_lcd_panel_dev_config_t panel_config = {
 | 
						|
        .reset_gpio_num = EXAMPLE_PIN_NUM_RST,
 | 
						|
        .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
 | 
						|
        .bits_per_pixel = 16,
 | 
						|
    };
 | 
						|
    // Initialize the LCD configuration
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
 | 
						|
 | 
						|
    // Turn off backlight to avoid unpredictable display on the LCD screen while initializing
 | 
						|
    // the LCD panel driver. (Different LCD screens may need different levels)
 | 
						|
    ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL));
 | 
						|
 | 
						|
    // Reset the display
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
 | 
						|
 | 
						|
    // Initialize LCD panel
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
 | 
						|
 | 
						|
    // Turn on the screen
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true));
 | 
						|
 | 
						|
    // Swap x and y axis (Different LCD screens may need different options)
 | 
						|
    ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true));
 | 
						|
 | 
						|
    // Turn on backlight (Different LCD screens may need different levels)
 | 
						|
    ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL));
 | 
						|
 | 
						|
    // Initialize the effect displayed
 | 
						|
    ESP_ERROR_CHECK(pretty_effect_init());
 | 
						|
 | 
						|
    // "Rotate or not" flag
 | 
						|
    bool is_rotated = false;
 | 
						|
 | 
						|
    // Allocate memory for the pixel buffers
 | 
						|
    for (int i = 0; i < 2; i++) {
 | 
						|
        s_lines[i] = heap_caps_malloc(EXAMPLE_LCD_H_RES * PARALLEL_LINES * sizeof(uint16_t), MALLOC_CAP_DMA);
 | 
						|
        assert(s_lines[i] != NULL);
 | 
						|
    }
 | 
						|
 | 
						|
    // Start and rotate
 | 
						|
    while (1) {
 | 
						|
        // Set driver configuration to rotate 180 degrees each time
 | 
						|
        ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, is_rotated, is_rotated));
 | 
						|
        // Display
 | 
						|
        display_pretty_colors(panel_handle);
 | 
						|
        is_rotated = !is_rotated;
 | 
						|
    }
 | 
						|
}
 |