Skip to content

Fix deep_sleep() opcode after the protocol 2.1 split (0x0052 -> 0x0053) - #160

Open
sappafrancesco wants to merge 1 commit into
OpenDisplay:mainfrom
sappafrancesco:deep-sleep-power-off-split
Open

sappafrancesco wants to merge 1 commit into
OpenDisplay:mainfrom
sappafrancesco:deep-sleep-power-off-split

Conversation

@sappafrancesco

Copy link
Copy Markdown

Fixes #159.

Protocol 2.1 split the old single 0x0052 opcode in two (per
opendisplay-protocol's opendisplay_protocol.h):

  • CMD_POWER_OFF (0x0052) — a hard rail-cut for boards with a D-FF
    power latch; NACKs (OD_ERR_POWER_OFF_UNSUPPORTED) on latch-less
    boards.
  • CMD_DEEP_SLEEP (0x0053) — host-commanded timer deep sleep, with an
    optional big-endian u16 one-shot wake-timer duration (60 s firmware
    floor). This is what deep_sleep() used to send on 0x0052.

deep_sleep() still sends 0x0052, so on current latch-less firmware
it now NACKs instead of sleeping — verified live on an M5Stack
PaperS3 (firmware protocol v2.2) per the issue.

Changes

  • CommandCode.DEEP_SLEEP is now 0x0053; added
    CommandCode.POWER_OFF = 0x0052.
  • build_deep_sleep_command() builds 0x0053 and takes an optional
    duration_seconds, appended as a big-endian u16 (not validated
    client-side against the firmware's 60 s floor, matching how other
    firmware-enforced limits are handled elsewhere in this library).
  • Added build_power_off_command() (0x0052) and
    OpenDisplayDevice.power_off(), mirroring deep_sleep()'s existing
    tolerate-the-disconnect handling — a board with a power latch is
    expected to ACK 0x0052 and then drop the link exactly like
    deep_sleep()'s targets do, so the same ACK/NACK/timeout/disconnect
    logic applies.
  • deep_sleep()'s NACK check moved from the 0xFF52 error frame to
    0xFF53 to match the new opcode.

Testing

tests/unit/test_device_deep_sleep.py renamed its 0x0052 assertions
to 0x0053, added a duration-parameter test, and added power_off()
coverage (ACK, NACK, write-drop, read-disconnect). Added
CommandCode.POWER_OFF/DEEP_SLEEP value assertions and
build_power_off_command()/duration-parameter coverage to
test_protocol_commands.py.

uv run pytest        -> 1035 passed
uv run ruff check     -> clean
uv run ruff format    -> clean
uv run mypy src/      -> clean (strict)
uv run pylint src/    -> 10.00/10

Protocol 2.1 split the old single 0x0052 opcode in two: POWER_OFF
(0x0052) is a hard rail-cut for boards with a D-FF power latch and
NACKs on latch-less boards, while CMD_DEEP_SLEEP moved to 0x0053 (with
an optional big-endian u16 one-shot wake-timer duration, 60 s firmware
floor). deep_sleep() still sent 0x0052, so it NACKs on current
latch-less firmware.

Fixes OpenDisplay#159 (verified live on an M5Stack PaperS3, firmware protocol
v2.2, per the issue).

- CommandCode: DEEP_SLEEP is now 0x0053, added POWER_OFF = 0x0052.
- build_deep_sleep_command() now builds 0x0053 and takes an optional
  duration_seconds, appended as a big-endian u16.
- Added build_power_off_command() for 0x0052, and a device.power_off()
  method mirroring deep_sleep()'s existing tolerate-the-disconnect
  behavior (same ACK/NACK/timeout/disconnect handling, since a board
  with a power latch is expected to ACK and then drop the link exactly
  like deep_sleep()'s targets do).
- deep_sleep()'s NACK check moved from 0xFF52 to 0xFF53 to match.

Updated test_device_deep_sleep.py (renamed from testing 0x0052 to
0x0053, added a duration test) and added power_off() tests plus
CommandCode/build_power_off_command coverage in
test_protocol_commands.py.

Checked:
```
uv run pytest        -> 1035 passed
uv run ruff check     -> clean
uv run ruff format    -> clean
uv run mypy src/      -> clean (strict)
uv run pylint src/    -> 10.00/10
```
@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

deep_sleep() sends CMD_POWER_OFF 0x0052; protocol moved host deep sleep to CMD_DEEP_SLEEP 0x0053

1 participant