Skip to content

SSD1309 OLED

Solomon Systech SSD1309 128×64 monochrome OLED (2.42″ / 2.4″ glass), I²C. The SSD1306's sibling.

Live catalog

Prefer labwired_describe with the catalog id over guessing pins or addresses.

Status at a glance

Aspect Status
Catalog id oled-ssd1309
Bus I²C
Address 0x3C (SA0 low) / 0x3D (SA0 high)
Source configs/devices/ssd1309.yaml (declarative display, no Rust model)
Datasheet Solomon Systech SSD1309 Rev 1.1 (Jul 2011): §8.1.5, §8.6, §9 Tables 9-1..9-5, §10.3
Tier smoke-proven (crates/core/tests/everyday_display_set.rs)

Pins / attachment

Pin / net Role
SDA I²C SDA
SCL I²C SCL
VDD/GND Power (digital twin)

Support matrix

Behavior Status Notes
GDDRAM, 8 pages × 128 columns ✅ Control byte 0x00 = commands, 0x40 = data
Page / horizontal / vertical addressing (20h) ✅ Resets to PAGE mode (Table 9-3); page mode wraps COL127 → COL0
21h / 22h window, B0h–B7h, 00h–1Fh pointers ✅ 21h clamps to 127; 22h masks to 3 bits
AEh / AFh display off/on ✅
Init parameter bytes (81h, FDh, DCh, A8h, D3h, D5h, D9h, DAh, DBh, scroll setups) ✅ Consumed for their counts, never decoded as opcodes
Contrast, remap, scan direction, scroll, start line ❌ Change the glass, not GDDRAM
Command lock (FDh A[2] = 1) ❌ Consumed, lock not applied
Charge pump (8Dh) ❌ The SSD1309 has none (external 7–16 V VCC)
SPI / parallel interfaces ❌ This descriptor is the I²C strap

How to run

  1. Place the part and an MCU in Playground, or add it to a system YAML:
    external_devices:
      - id: "oled"
        type: "oled-ssd1309"
        connection: "i2c0"
    
  2. Agent: labwired_list → labwired_describe id=oled-ssd1309 → wire → labwired_validate → labwired_run / labwired_verify.
  3. Smoke: cargo test -p labwired-core --test everyday_display_set. It checks display-off at reset, then sends an init sequence whose parameter bytes are themselves valid opcodes. The datasheet's own Figure 10-2 example (B2h / 03h / 10h → PAGE2, column 3) follows, then the page-mode wrap and a horizontal-mode window. It compares the whole 1024-byte GDDRAM against the eight bytes written. The negative control requires the check to FAIL against a panel that reads all 0x00 or all 0xFF.

Limitations

  • SSD1306 firmware that sends 8D 14 gets 14h decoded as Set Higher Column Start Address, which is what the SSD1309 table defines that byte as. The datasheet calls unlisted patterns "unexpected results".
  • This descriptor resets to page addressing per its datasheet; oled-ssd1306 resets to horizontal.

See the YAML header for the full datasheet trace and every named approximation.