Skip to content

Add support for ASRock Steel Legend 360 LCD - #10

Merged
emaspa merged 2 commits into
emaspa:mainfrom
Ulfy:add-asrock-steel-legend-360-lcd
Sep 17, 2026
Merged

emaspa merged 2 commits into
emaspa:mainfrom
Ulfy:add-asrock-steel-legend-360-lcd

Conversation

@Ulfy

@Ulfy Ulfy commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Adds ASRock Steel Legend 360 LCD support using the existing Thermaltake/ASRock HID backend.

Changelog:

  • Adds the LCD as a supported 480×480 panel.
  • Adds Linux udev perms for 26CE:0A11.
  • Adds the Steel Legend image packet format.
  • Adds the required power resume and realtimeDisplay enable initialization sequence. (Necessary after a full power cycle)

The protocol behavior was verified by comparing USB captures from ASRock Polychrome Display on Windows with the Linux USB traffic.

Existing Thermaltake/ASRock Phantom Gaming behavior is preserved through product-specific handling. I know it's not very DRY to reproduce the Build/Send Packet commands, but I didn't want to alter that method handling for the pre-existing code.

@Ulfy

Ulfy commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author
image

- Remove the Information log in SendJpegFrame; it fired on every frame
  for every panel model.
- Sample the byte-3 timestamp once per frame so all chunks of a frame
  carry the same value.
- Share the realtimeDisplay disable path, then suspend for Steel Legend.
- Formatting cleanup; add the panel to the README device table.
@emaspa
emaspa merged commit ef5eab4 into emaspa:main Sep 17, 2026
@emaspa

emaspa commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Thanks for this, @Ulfy! It's merged and shipped in v0.3.4 (deb, rpm, tarball, and infopanel-bin on the AUR).

Before merging I pushed a small follow-up commit (5746974) onto your branch:

  • Removed the per-frame Sending JPEG frame log. It was at Information level and fired on every frame for every panel model, so up to 60 lines a second.
  • Byte 3 of the image header is now read once per frame, not once per chunk. Before, a frame that crossed a second boundary could carry two different values across its chunks.
  • The Steel Legend shutdown now shares the regular realtimeDisplay disable path, then sends power suspend. The commands and their order are unchanged.
  • Formatting cleanup, plus a README device-table row for 26CE:0A11.

Apart from the removed log line, the bytes on the wire should match your version exactly. I don't have a Steel Legend here, though, so could you install 0.3.4 and confirm the panel still works? In particular:

  1. It lights up and shows your profile after a cold boot, from a full power cycle.
  2. Frames update smoothly with no corruption or dropped frames.
  3. The panel goes to sleep when you quit InfoPanel, and wakes again on the next launch.

Replug the panel once after installing so the udev rule applies. If anything's off, attach a log from ~/.local/share/InfoPanel/ and I'll take a look.

@Ulfy

Ulfy commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Ok, great! So after starting fresh with v0.3.4 from the AUR, here is what I found:

  • works after a full power cycle
  • frames and sensors update normally
  • quitting InfoPanel sleeps the panel
  • relaunching InfoPanel wakes it and resumes normal streaming

I did find a separate suspend/resume issue. If the PC sleeps while InfoPanel is running, the LCD is black after wake. The kernel reports an xHCI resume error/reinit on the USB controller hosting the LCD. Toggling the stream off/on successfully lights up the panel, but the profile image/sensors are just static. Restarting the stream within InfoPanel or killing/launching InfoPanel doesn't fix it... only a full power cycle clears the issue.

So the Steel Legend support itself looks good; sans the suspend/resume issue. I attached the relevant infopanel log & a snippet from journalctl during that timeframe. There are no InfoPanel log entries at the actual system resume time. Systemd-sleep froze user.slice at 00:11:16 and thawed it at 00:12:24, but InfoPanel did not log any resume/reinit activity. The next InfoPanel device activity was only when I manually toggled streaming at 00:16.

journalctl.log
infopanel.log

Thanks!

@Ulfy

Ulfy commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

I narrowed the suspend issue down further. The USB behavior is identical between working and failing resumes: the HID instance is the same, and both working and failing resumes show the xHCI message.

The suspend duration seems to matter: A short suspend (say 12s) resumes normally, while the AIO LCD remains lit. A suspend over a minute, during which the LCD eventually goes dark, resumes in a broken state.

This reminded me that the Windows Polychrome capture sent POST timeout {"value":60} during the init. It may be that after ~60 seconds without traffic the panel exits realtime-display/power state? Maybe InfoPanel is frozen/thawed across the system suspend and never repeats the startup handshake. Does this mean we need to perform another power resume & realtimeDisplay enable sequence? Food for thought.

emaspa added a commit that referenced this pull request Sep 18, 2026
The Windows app stops its panel tasks on SystemEvents.PowerModeChanged
Suspend and starts them again on Resume. The Linux port had no equivalent:
the process was simply frozen mid-stream and thawed later. Ulfy reported
on PR #10 that the ASRock Steel Legend 360 comes back dark after a
suspend longer than about a minute (its firmware leaves realtime display
after that long without frames) and then ignores a fresh handshake until
a full power cycle. Only a clean suspend before the system sleeps avoids
that state.

Adds a SleepMonitor that subscribes to logind's PrepareForSleep on the
system bus through Tmds.DBus.Protocol (already shipped with Avalonia) and
holds a 'sleep' delay inhibitor. Before sleep it stops all eight panel
tasks, which sends each panel its sleep or close command, then releases
the inhibitor so the suspend proceeds. After resume it re-takes the
inhibitor and restarts the panel tasks a second later. The state machine
is unit-tested; the logind side was verified here: systemd-inhibit lists
InfoPanel with a 'sleep' delay lock while the app runs. Without a system
bus the app logs once and behaves as before.
@emaspa

emaspa commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Thanks for the confirmation on 0.3.4, and for narrowing the suspend issue down. Your reading matches what I found.

The Windows app stops its panels on the suspend event and restarts them on resume. The Linux port never had that: the process was frozen mid-stream and thawed later, so nothing was sent to the panel for the whole suspend. That is consistent with your timing: a short suspend stays within the panel's idle window, a long one does not, and once the firmware has left realtime display on its own it evidently no longer accepts a handshake until power is cut. It also explains why nothing shows in the InfoPanel log at resume time.

0.3.6 adds the missing piece. InfoPanel now listens to logind's PrepareForSleep and holds a sleep delay lock. Before the system suspends it stops every panel, which for the Steel Legend sends realtimeDisplay disable and power suspend, and only then lets the suspend proceed. After resume it restarts the panels a second later. The log will show "System is going to sleep: stopping panel devices" and "System resumed from sleep: restarting panel devices" around each suspend.

I verified here that the app takes the delay lock and that systemctl suspend stops the panels before the system goes down, but I do not have a Steel Legend to suspend against, so could you try a suspend of a few minutes on 0.3.6? On Arch it is yay -S infopanel-bin once the AUR job has run. If the panel still comes back wrong, the log from ~/.local/share/InfoPanel/logs/ around the suspend would help, and then the next thing to try is that POST timeout command from your capture.

@Ulfy

Ulfy commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

That did the trick. Did a few rounds of testing and it resumed perfectly. Here is the logging I see as well...

Going to sleep:

9月 19 22:44:31 org_kde_powerdevil[2402]: [ 2447][1854.021156] (ldbus_handle_message)Received dbus signal PrepareForSleep(true=prepare)
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] System is going to sleep: stopping panel devices
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] ThermaltakeHidDevice: realtimeDisplay disable OK
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] ThermaltakeHidDevice: power suspend OK
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] Stopped all Thermaltake panel devices
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] Stopped all JL panel devices
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] Stopped all VMAX panel devices
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] Stopped all Jonsbo panel devices
9月 19 22:44:31 infopanel[4284]: [22:44:31 INF] Stopped all Lian Li panel devices

Waking up:

2026-09-20 00:34:02.241 +09:00 [INF] System resumed from sleep: restarting panel devices
2026-09-20 00:34:03.567 +09:00 [INF] Started Thermaltake panel device
2026-09-20 00:34:03.567 +09:00 [INF] ThermaltakeDevice : Opening (attempt 1)
2026-09-20 00:34:03.568 +09:00 [INF] ThermaltakeHidDevice: Scanning for VID=26CE PID=0A11
2026-09-20 00:34:03.624 +09:00 [INF] ThermaltakeHidDevice: Opened /sys/devices/pci0000:00/0000:00:02.1/0000:04:00.0/0000:05:0c.0/0000:0d:00.0/usb6/6-7/6-7.4/6-7.4:1.0/0003:26CE:0A11.0005/hidraw/hidraw4
2026-09-20 00:34:03.624 +09:00 [INF] ThermaltakeDevice : Handshake
2026-09-20 00:34:03.624 +09:00 [INF] ThermaltakeHidDevice: Starting handshake
2026-09-20 00:34:03.674 +09:00 [INF] ThermaltakeHidDevice: power resume OK
2026-09-20 00:34:04.185 +09:00 [INF] ThermaltakeHidDevice: realtimeDisplay OK
2026-09-20 00:34:04.285 +09:00 [INF] ThermaltakeHidDevice: Steel Legend handshake complete

Thank you!

proof.mp4

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.

2 participants