Add SSD1363 256x128 greyscale OLED driver#421
Conversation
The SSD1363 has two non-obvious hardware differences from SSD1362/SSD1306 that required reverse-engineering against the manufacturer's example: 1. DC-pin protocol: the SSD1363 treats DC as a per-byte signal, not a mode signal. Only the command opcode byte uses DC-LOW; all parameter bytes and pixel data use DC-HIGH. Without this, parameter bytes land as command opcodes — for example, a row-end value of 0x2F activates hardware scroll, preventing the row window from ever being set. Overriding command() to route parameter bytes through data() fixes this (same pattern as ssd1322). 2. Byte-pair swap: within each 2-byte column address the pair must arrive in reverse order due to the panel's column-remap wiring. display() is overridden to swap adjacent byte pairs in the output buffer before writing. This matches the manufacturer's er_oled_bitmap_gray() reference implementation for the ZJY270S0700XG21 2.7" module. Other differences from SSD1362: - SETCONTRAST = 0xC1 (not 0x81) - 0xCA for mux ratio (not 0xA8) - 0xAD for IREF (not 0xAB) - Column addresses: pixel_x // 4 + 8 (panel has a +8 hardware offset) - 0x5C Write-RAM required before each pixel burst Tested on Raspberry Pi 4 + ZJY270S0700XG21 via SPI0. Gradient, greyscale bars, anti-aliased text, and contrast sweep all render correctly across the full 256x128 pixel area. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for the SSD1363 OLED display, implementing its specific initialization sequence, command protocol, and byte-swapping requirements for rendering. The feedback identifies a need for 4-pixel column alignment via _inflate_bbox to support partial updates correctly and suggests optimizing the byte-swapping logic in the display method for better efficiency.
Remove extra spaces used for visual alignment of assignment operators in the ssd1363 constants and _set_position method, per PEP8 E221. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the explicit Python loop with bytearray slice assignment. buf[0::2], buf[1::2] = buf[1::2], buf[0::2] produces the same byte-pair swap in a single operation, avoiding the O(n) loop overhead on a 16 KB buffer and the intermediate list conversion. Suggested by code review on PR rm-hull#421. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
can you also add the datasheet pdf to https://github.com/nimarchetti/luma.oled/blob/add-ssd1363/doc/intro.rst |
rm-hull
left a comment
There was a problem hiding this comment.
Looks fine to me. Happy to merge when all comments resolved. When merged I'll push out a new version
Updated the list of supported display drivers and removed a rate-limited badge.
thijstriemstra
left a comment
There was a problem hiding this comment.
thanks! I also added some doc updates.
What
Adds
ssd1363device class andluma.oled.const.ssd1363constants for theSSD1363 256×128 4-bit greyscale OLED controller, tested on the ZJY270S0700XG21
2.7" module wired to a Raspberry Pi 4 via SPI0.
Why two overrides are needed
DC-pin protocol
The SSD1363 treats DC as a per-byte signal rather than a mode signal. Only
the command opcode byte uses DC-LOW; all parameter bytes and pixel data use
DC-HIGH. Sending parameter bytes at DC-LOW causes them to be misinterpreted as
new command opcodes — for example, a row-address end value of 47 (0x2F)
activates hardware scroll and prevents the row window from being set.
command()is overridden to route parameter bytes throughdata()(DC-HIGH).This is the same pattern used by
ssd1322.Byte-pair swap
Within each 2-byte column address the bytes must arrive in reverse order due to
the panel's column-remap wiring.
display()is overridden to swap adjacentbyte pairs in the output buffer before writing. This matches the swap shown in
the manufacturer's
er_oled_bitmap_gray()reference implementation for thismodule.
Because
command()already handles the DC protocol correctly, the base-classcontrast()works without a further override.Other hardware differences from SSD1362
pixel_x // 2pixel_x // 4 + 8Testing
Tested on Raspberry Pi 4 + ZJY270S0700XG21 2.7" OLED via SPI0 at 8 MHz.
Gradient fill, greyscale bars, anti-aliased text, and contrast sweep (0–255)
all render correctly across the full 256×128 pixel area.
Unit tests in
tests/test_ssd1363.pyfollow the existingtest_ssd1362.pypattern and cover: init sequence, invalid dimensions, hide/show, contrast,
greyscale display, and monochrome display.
fixes #401