Skip to content

SODAVK/SSD1306_OLED_RISC-V_LP-Core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

LP Core SSD1306 0.96" (128x64) OLED Driver for ESP32-C6 & ESP32-C5

A lightweight, hardware-optimized graphics and text library written from scratch for the RISC-V LP Core (ULP) coprocessor inside ESP32-C6 and ESP32-C5 SoC.

This library enables the Low-Power (LP) core to completely offload monochrome OLED display rendering via the hardware LP_I2C peripheral. The High-Performance (HP) main core can remain in Deep Sleep or execute independent high-load tasks (such as Wi-Fi 6 or BLE communication) without interrupting the display output.

πŸ“· Media Demo

Demonstration gfx Demonstration text

Left: Rendering performance test (stress test GFX) |Right: GFX and text static demo on ESP32-C6 LP 20MHz


⚑ Key Specifications

  • RAM Footprint: The library standalone footprint is only 2.5 KB to 4 KB of LP SRAM (including the framebuffer). With full system drivers, ULP bootloader components, and stack allocation, real runtime consumption scales to ~6 KB to 8 KB out of the 16 KB total available. Completely static allocation.
  • Performance: Capable of rendering complex scenes (tested with 150 bounding/colliding objects at 100% LP Core load.
  • Auto-Platform Pin Mapping: Target I2C pins are handled automatically at compile-time based on the selected target framework (GPIO 6/7 for ESP32-C6; GPIO 2/3 for ESP32-C5). No manual pin configuration is required in the codebase.
  • Hardware Time-Tracking: Implements a precise microsecond timer (oled_lp_get_time_us) with hardware clock-tick calibration and overflow protection, compensating for the lack of esp_timer on the LP Core.

πŸ›  Features & Graphics API

  • Core Control: Framerate configuration (1–30 FPS), power state toggling (sleep/wake), contrast adjustment, 180Β° display rotation, and inversion.
  • Geometry Engine: Standard primitives including pixels, lines (1 to 4 pixels thick), rectangles, frames, circles, and capsules with adjustable corner radius.
  • Advanced Rendering: Built-in chess-pattern fill mode for efficient semi-transparent overlays and shading on monochrome matrices.
  • Text Engine: Fast 5x7 ASCII font rendering with fast scaling (1x to 4x) and 180Β° string mirroring.

πŸ“… Development Context

  • Framework Version: Developed and fully tested on the official ESP-IDF master branch (v6.0.DEV state as of July 1, 2026).

πŸ“‚ Repository Structure

SSD1306_OLED_RISC-V_LP-Core/
β”œβ”€β”€ LICENSE                  # License MIT
β”œβ”€β”€ CMakeLists.txt           # Top-level project CMake
β”œβ”€β”€ README.md                # Documentation
β”œβ”€β”€ assets/                  # Media files (Images & GIF)
β”œβ”€β”€ main/
β”‚   β”œβ”€β”€ CMakeLists.txt       # Component build script with ULP integration
β”‚   β”œβ”€β”€ lp_core_ssd1306.c    # Main HP Core initialization application
β”‚   └── ulp/
β”‚       β”œβ”€β”€ main.c           # Entry point for the LP Core application
β”‚       β”œβ”€β”€ ssd1306_lp.c     # Library implementation
β”‚       └── ssd1306_lp.h     # Library header

πŸš€ Integration Guide

To integrate this library into any existing ESP-IDF v6.0+ project, follow these steps:

1. Copy Files

Place ssd1306_lp.c and ssd1306_lp.h directly into your component's ulp/ directory.

2. Update Component CMakeLists.txt

Modify your main/CMakeLists.txt to include the ulp and esp_driver_i2c requirements, and register the source files inside the ulp_embed_binary function as shown below:

# Set usual component variables
set(app_sources "lp_core_ssd1306.c")

idf_component_register(SRCS \${app_sources}
                       REQUIRES ulp esp_driver_i2c
                       WHOLE_ARCHIVE)

# ULP source registration
set(ulp_app_name ulp_\${COMPONENT_NAME})
set(ulp_sources 
    "ulp/main.c"
    "ulp/ssd1306_lp.c" # <-- Add library source file here
)

set(ulp_exp_dep_srcs \${app_sources})
ulp_embed_binary(\${ulp_app_name} "\${ulp_sources}" "\${ulp_exp_dep_srcs}")

3. Configure via Menuconfig

Before building, you must explicitly enable the LP Core coprocessor and allocate enough memory for the combined driver and application footprint:

  1. Run idf.py menuconfig
  2. Navigate to: Component config ➑️ Ultra Low Power (ULP) Co-processor
  3. Enable Enable Ultra Low Power (ULP) Coprocessor
  4. Set ULP Co-processor type to LP Core RISC-V
  5. Change ULP memory size (bytes) to a minimum of 8192 (10240 or 12288 is recommended if you plan to add more custom user logic).

4. Usage

Include the header file inside your LP Core source code (ulp/main.c):

#include "ssd1306_lp.h"

πŸ“‹ API Reference

System & Time Management

  • void oled_lp_init(void); β€” Initialize display, calibrate timer, start at 24 FPS by default.
  • void oled_lp_deinit(void); β€” Deinitialize: turn off matrix, clear buffer, disable charge pump.
  • void oled_lp_time_init(void); β€” Hardware measurement of LP Core frequency (ticks per 1 Β΅s).
  • uint64_t oled_lp_get_time_us(void); β€” Time in Β΅s with overflow protection and auto-recalibration.
  • void oled_lp_set_fps(uint8_t fps); β€” Set target frame rate (1..30 FPS).

Power Management & Matrix Parameters

  • void oled_lp_power_on(void); β€” Quick wake from sleep (turn on matrix).
  • void oled_lp_power_off(void); β€” Quick sleep mode (turn off matrix for power saving).
  • void oled_lp_set_contrast(uint8_t contrast); β€” Matrix brightness (0x00 .. 0xFF).
  • void oled_lp_set_inversion(bool invert); β€” Screen color inversion (true = inverted).
  • void oled_lp_set_rotation_180(bool rotate); β€” Rotate display 180 degrees.

Frame Buffer & Synchronization

  • void oled_lp_clear_buffer(void); β€” Clear local RAM buffer (1024 bytes) to zero.
  • bool oled_lp_is_dirty(void); β€” Check if the buffer has changed since last transmission.
  • void oled_lp_refresh_once(void); β€” Force transmit buffer to I2C bus regardless of FPS.
  • bool oled_lp_refresh_sync(void); β€” Send frame based on FPS schedule (if buffer is "dirty"). Returns true on send.

Graphics & Typography Rendering

  • void oled_lp_draw_pixel(uint8_t x, uint8_t y, bool set); β€” Pixel (set: true = on, false = off).
  • void oled_lp_draw_frame(void); β€” Draw 1-pixel outline border around the screen.
  • void oled_lp_draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t thickness); β€” Line (thickness 1..4).
  • void oled_lp_draw_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t r, uint8_t t, bool solid, bool chess); β€” Rectangle (w-width, h-height, r-corner radius, t-border thickness, solid-fill, chess-checkerboard fill).
  • void oled_lp_draw_string(uint8_t x, uint8_t y, const char* str, uint8_t scale, bool flip_180); β€” Text (5x7 ASCII font). scale-multiplier (1..4x), flip_180-mirror string horizontally/vertically.

πŸ›‘ Hardware Limitation Notice

This library relies strictly on the hardware LP_I2C peripheral architecture implemented in the ESP32-C6 and ESP32-C5 series. Due to architectural differences and specific hardware behavior of the RTC I2C controller on the ESP32-S3 SoC, this codebase is fundamentally incompatible with the ESP32-S3 ULP RISC-V coprocessor and cannot be run on it.


πŸ”’ License

This project is licensed under the MIT License. You are free to use, modify, and distribute this software in both commercial and open-source applications without restriction. Thanks


About

Light SSD1306 0.96" OLED Display graphics & text library for ESP32-C6 and ESP32-C5 RISC-V LP Core (ESP-IDF v6.0+).

Topics

Resources

License

Stars

3 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors