Skip to content

Reject unsupported color schemes at direct-write START#3

Open
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/reject-unsupported-color-schemes
Open

Reject unsupported color schemes at direct-write START#3
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/reject-unsupported-color-schemes

Conversation

@balloob

@balloob balloob commented Jul 6, 2026

Copy link
Copy Markdown

Problem

map_panel_ic_to_model_id() (EPD/EPD_driver.c:325) maps any nonzero color_scheme to a BWR model, and handle_direct_write_start() sizes the transfer using a single BWR plane byte count (row_bytes * height). The nRF firmware genuinely renders only two schemes: BW (0) and BWR (1). For BWY (2), 2bpp (3/5) and 4-gray (4/6), the client streams a payload of a different size than the firmware computes, so it over/under-runs display RAM and refreshes garbage — while still ACKing success to the client.

Fix

At direct-write START, check the display's configured color_scheme. If it is anything other than 0 (BW) or 1 (BWR), reply with the standard 4-byte NACK frame {0xFF, cmd, RESP_ERR_UNSUPPORTED_SCHEME, 0x00} and return before powering the panel or streaming. The unsupported color schemes are not implemented; they are cleanly rejected.

Accepted vs rejected schemes

  • Accepted: 0 (BW), 1 (BWR) — behavior unchanged.
  • Rejected (NACK): 2 (BWY), 3/5 (2bpp), 4/6 (4-gray), and any other value; also a NULL display_config.

Error frame

{0xFF, 0x70, 0x02, 0x00}0x70 is the low byte of CMD_DIRECT_WRITE_START, 0x02 is the new RESP_ERR_UNSUPPORTED_SCHEME code. This matches the existing 4-byte NACK convention already used for config errors.

Client recognition

The START ACK is {0x00, 0x70} → command code 0x0070, which the client's validate_ack_response() accepts. The NACK's first two bytes are 0xFF70, which is not in the valid ACK set {0x0070, 0x8070}, so validate_ack_response() raises InvalidResponseError (protocol/responses.py). The client fails fast — it does not hang or proceed to stream.

Testing

arm-none-eabi-gcc and the nRF SDK build environment are not available here, so a full firmware build was not run. The changed logic was extracted into an isolated translation unit and compiled clean with gcc -std=c11 -Wall -Wextra -Werror (including the logging-disabled path). Change is surgical: BW and BWR paths are untouched.

🤖 Generated with Claude Code

https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR

nRF firmware only renders BW (color_scheme 0) and BWR (color_scheme 1).
map_panel_ic_to_model_id() maps every nonzero color_scheme to a BWR model
and direct-write START sizes the transfer with a single BWR plane byte
count. For BWY, 2bpp and 4-gray schemes the client streams a differently
sized payload, so the firmware over/under-runs RAM and refreshes garbage
while still ACKing success.

Check display_config->color_scheme at direct-write START and reject any
scheme other than 0/1 with the standard 4-byte NACK frame
{0xFF, cmd, RESP_ERR_UNSUPPORTED_SCHEME, 0x00} before powering the panel.
The client's validate_ack_response() sees 0xFF70 instead of the 0x0070
ACK echo and raises InvalidResponseError, so it fails fast instead of
rendering garbage. BW and BWR are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant