cleishm/idfxx_lcd_ili9341

1.0.0

Latest
uploaded 12 hours ago
ILI9341 LCD panel driver (240x320)

readme

# idfxx_lcd_ili9341

ILI9341 LCD panel driver (240x320).

📚 **[Full API Documentation](https://cleishm.github.io/idfxx/group__idfxx__lcd.html)**

## Features

- ILI9341 display controller driver (240x320 displays)
- Display orientation and mirroring controls
- Integration with `idfxx_lcd` panel I/O

## Requirements

- ESP-IDF 5.5 or later
- C++23 compiler
- `idfxx_lcd` component (provides `panel` base class and `panel_io`)

## Installation

### ESP-IDF Component Manager

Add to your project's `idf_component.yml`:

```yaml
dependencies:
  idfxx_lcd_ili9341:
    version: "^1.0.0"
```

Or add `idfxx_lcd_ili9341` to the `REQUIRES` list in your component's `CMakeLists.txt`.

## Usage

### Basic Example

If `CONFIG_COMPILER_CXX_EXCEPTIONS` is enabled:

```cpp
#include <idfxx/spi/master>
#include <idfxx/lcd/panel_io>
#include <idfxx/lcd/ili9341>
#include <idfxx/log>

try {
    using namespace frequency_literals;

    // Create SPI bus
    idfxx::spi::master_bus spi_bus(
        idfxx::spi::host_device::spi2,
        idfxx::spi::dma_chan::ch_auto,
        idfxx::spi::bus_config {
            .mosi = idfxx::gpio_23,
            .miso = idfxx::gpio_19,
            .sclk = idfxx::gpio_18,
            .max_transfer_sz = 4096,
        }
    );

    // Create panel I/O
    idfxx::lcd::panel_io panel_io(
        spi_bus,
        idfxx::lcd::panel_io::spi_config {
            .cs_gpio = idfxx::gpio_5,
            .dc_gpio = idfxx::gpio_2,
            .spi_mode = 0,
            .pclk_freq = 40_MHz,
            .trans_queue_depth = 10,
            .lcd_cmd_bits = 8,
            .lcd_param_bits = 8,
        }
    );

    // Create ILI9341 panel
    idfxx::lcd::ili9341 panel(
        panel_io,
        idfxx::lcd::panel::config {
            .reset_gpio = idfxx::gpio_4,
            .rgb_element_order = idfxx::lcd::rgb_element_order::bgr,
            .bits_per_pixel = 16,
        }
    );

    // Operations throw on error
    panel.swap_xy(true);
    panel.mirror(false, true);
    panel.display_on(true);

} catch (const std::system_error& e) {
    idfxx::log::error("LCD", "Error: {}", e.what());
}
```

### Result-based API

If `CONFIG_COMPILER_CXX_EXCEPTIONS` is *not* enabled, the result-based API must be used:

```cpp
// Create SPI bus
auto spi_bus_result = idfxx::spi::master_bus::make(
    idfxx::spi::host_device::spi2,
    idfxx::spi::dma_chan::ch_auto,
    { /* ... */ }
);
if (!spi_bus_result) {
    idfxx::log::error("LCD", "Failed to create SPI bus: {}", spi_bus_result.error().message());
    return;
}
auto spi_bus = std::move(*spi_bus_result);

// Create panel I/O
auto panel_io_result = idfxx::lcd::panel_io::make(
    spi_bus,
    { /* ... */ }
);
if (!panel_io_result) {
    idfxx::log::error("LCD", "Failed to create panel I/O: {}", panel_io_result.error().message());
    return;
}
auto panel_io = std::move(*panel_io_result);

// Create ILI9341 panel
auto panel_result = idfxx::lcd::ili9341::make(
    panel_io,
    { /* ... */ }
);
if (!panel_result) {
    idfxx::log::error("LCD", "Failed to create panel: {}", panel_result.error().message());
    return;
}
auto panel = std::move(*panel_result);

// Initialize display
panel.try_display_on(true);

idfxx::log::info("LCD", "Display initialized successfully");
```

### Using a Named Config Variable

When storing the config in a variable before passing it, use `std::move()` since the config
struct is move-only:

```cpp
idfxx::lcd::panel::config panel_config{
    .reset_gpio = idfxx::gpio_4,
    .rgb_element_order = idfxx::lcd::rgb_element_order::bgr,
    .bits_per_pixel = 16,
};

// Must use std::move() when passing a named config variable
idfxx::lcd::ili9341 panel(panel_io, std::move(panel_config));
```

### Display Control

```cpp
// Assumes panel_io and panel_config defined as in Basic Example above
idfxx::lcd::ili9341 panel(panel_io, std::move(panel_config));

// Swap X and Y axes for portrait/landscape
panel.swap_xy(true);

// Mirror display
panel.mirror(true, false);  // Mirror X, don't mirror Y

// Turn display on/off
panel.display_on(true);
```

### Display Orientation Examples

```cpp
// Portrait (default) - 240 wide x 320 tall
panel.swap_xy(false);
panel.mirror(false, false);

// Landscape - 320 wide x 240 tall
panel.swap_xy(true);
panel.mirror(true, false);

// Portrait (flipped)
panel.swap_xy(false);
panel.mirror(true, true);

// Landscape (flipped)
panel.swap_xy(true);
panel.mirror(false, true);
```

### Integration with LVGL

```cpp
#include <idfxx/lcd/ili9341>
#include <lvgl.h>

// Assumes panel_io and panel_config defined as in Basic Example above
idfxx::lcd::ili9341 panel(panel_io, std::move(panel_config));

// Get ESP-IDF handle for LVGL integration
esp_lcd_panel_handle_t handle = panel.idf_handle();

// Use with LVGL driver
// (See LVGL documentation for complete integration)
```

## API Overview

### `ili9341`

**Creation:**
- `make(panel_io, config)` - Create ILI9341 panel (result-based)
- `ili9341(panel_io, config)` - Constructor (exception-based, if enabled)

**Display Control:** (inherited from `panel` base class in `idfxx_lcd`)
- `try_swap_xy(swap)` - Swap X and Y axes (result-based)
- `try_mirror(mirrorX, mirrorY)` - Mirror display (result-based)
- `try_display_on(on)` - Turn display on/off (result-based)
- `swap_xy(swap)` - Swap X and Y axes (exception-based, if enabled)
- `mirror(mirrorX, mirrorY)` - Mirror display (exception-based, if enabled)
- `display_on(on)` - Turn display on/off (exception-based, if enabled)

**Properties:**
- `idf_handle()` - Get ESP-IDF panel handle

**Lifetime:**
- Non-copyable and move-only
- Destructor automatically cleans up panel resources

**Specifications:**
- Resolution: 240x320 pixels
- Color depth: 16-bit (RGB565)
- Interface: SPI

## Configuration

### `panel::config`

Configuration structure defined in `idfxx_lcd`:

- `reset_gpio` - Reset pin GPIO (`idfxx::gpio::nc()` if not used)
- `rgb_element_order` - RGB element order (`idfxx::lcd::rgb_element_order::rgb` or `::bgr`)
- `data_endian` - RGB data endian (`idfxx::lcd::rgb_data_endian::big` or `::little`)
- `bits_per_pixel` - Color depth (typically 16 for RGB565)
- `flags.reset_active_level` - Active level for the panel reset signal (`gpio::level::low` or `gpio::level::high`)
- `vendor_config` - Vendor-specific configuration (optional)

### Typical ILI9341 Configuration

```cpp
idfxx::lcd::panel::config panel_config{
    .reset_gpio = idfxx::gpio_4,                              // Or idfxx::gpio::nc()
    .rgb_element_order = idfxx::lcd::rgb_element_order::bgr,  // ILI9341 typically uses BGR
    .bits_per_pixel = 16,                                     // RGB565
};
```

## Important Notes

- **Dual API Pattern**: The component provides both result-based and exception-based APIs
  - `make()` returns `result<ili9341>` (always available)
  - Constructor throws `std::system_error` (requires `CONFIG_COMPILER_CXX_EXCEPTIONS`)
- The `panel_io` must be created before creating the panel
- The caller must ensure `panel_io` outlives the panel
- Reset pin is optional (use `idfxx::gpio::nc()` if not connected)
- RGB element order depends on specific display module (try both if colors are wrong)
- 16-bit color depth (RGB565) is most common for ILI9341
- Call `display_on(true)` after initialization to turn on the display
- The panel handle can be used with ESP-IDF LCD API or LVGL
- The `ili9341` class inherits from the `panel` base class provided by `idfxx_lcd`

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

Links

License: Apache-2.0

To add this component to your project, run:

idf.py add-dependency "cleishm/idfxx_lcd_ili9341^1.0.0"

download archive

Stats

  • Archive size
    Archive size ~ 13.38 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

cleishm/idfxx_lcd_ili9341 version: 1.0.0
|