mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-13 02:26:37 +00:00
On a Pi 5 the pinned rgbmatrix library drives the panel through the RP1 chip, and that path supports only row address types 0 and 2, parallel 1-3 and the regular / regular-pi1 / classic / adafruit-hat(-pwm) mappings (Rp1PioConfigSupported in lib/rp1/rp1_pio_backend.cc). For anything else CreateFromOptions returns NULL; the Python binding doesn't check, so the display process crashed on its first call into the matrix and systemd restarted it into the same crash every 10 seconds. - src/pi5_matrix_support.py: the rule and Pi 5 detection, matching the library's /proc/device-tree/model check - DisplayManager raises before creating the matrix, so it is a logged init failure (reported by /api/v3/hardware/status) and fallback mode - the config API rejects those settings on a Pi 5 when a request sets row_address_type, parallel or hardware_mapping - the Display form offers only row address types 0 and 2 on a Pi 5, and warns when a stored value can't be used - CLAUDE.md: re-check the rule whenever the submodule is bumped Review feedback on #586. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
80 lines
2.6 KiB
Python
80 lines
2.6 KiB
Python
"""The Pi 5 rule in src/pi5_matrix_support.py mirrors the pinned library.
|
|
|
|
Rp1PioPlatformDetected() and Rp1PioConfigSupported() in
|
|
rpi-rgb-led-matrix-master/lib/rp1/rp1_pio_backend.cc (commit 1ee4f76). When the
|
|
submodule is bumped and those change, these are the cases to revisit.
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from src import pi5_matrix_support as pi5 # noqa: E402
|
|
|
|
|
|
@pytest.fixture
|
|
def model_file(tmp_path, monkeypatch):
|
|
def write(model):
|
|
path = tmp_path / 'model'
|
|
# The device tree string is NUL-terminated.
|
|
path.write_bytes(model.encode() + b'\x00')
|
|
monkeypatch.setattr(pi5, 'MODEL_PATH', str(path))
|
|
return write
|
|
|
|
|
|
@pytest.mark.parametrize('model', [
|
|
'Raspberry Pi 5 Model B Rev 1.0',
|
|
'Raspberry Pi 500 Rev 1.0',
|
|
'Raspberry Pi Compute Module 5 Rev 1.0',
|
|
])
|
|
def test_pi5_family_is_detected(model_file, model):
|
|
model_file(model)
|
|
assert pi5.is_raspberry_pi_5()
|
|
|
|
|
|
@pytest.mark.parametrize('model', [
|
|
'Raspberry Pi 4 Model B Rev 1.5',
|
|
'Raspberry Pi Zero 2 W Rev 1.0',
|
|
'Raspberry Pi Compute Module 4 Rev 1.0',
|
|
])
|
|
def test_other_boards_are_not(model_file, model):
|
|
model_file(model)
|
|
assert not pi5.is_raspberry_pi_5()
|
|
|
|
|
|
def test_no_device_tree_is_not_a_pi5(tmp_path, monkeypatch):
|
|
monkeypatch.setattr(pi5, 'MODEL_PATH', str(tmp_path / 'missing'))
|
|
assert not pi5.is_raspberry_pi_5()
|
|
|
|
|
|
@pytest.mark.parametrize('hardware', [
|
|
{},
|
|
{'row_address_type': 0}, {'row_address_type': 2}, {'row_address_type': '2'},
|
|
{'parallel': 1}, {'parallel': 3},
|
|
{'hardware_mapping': 'regular'}, {'hardware_mapping': 'regular-pi1'},
|
|
{'hardware_mapping': 'classic'}, {'hardware_mapping': 'adafruit-hat'},
|
|
{'hardware_mapping': 'adafruit-hat-pwm'}, {'hardware_mapping': ''},
|
|
])
|
|
def test_what_the_pi5_path_supports(hardware):
|
|
assert pi5.pi5_unsupported_settings(hardware) is None
|
|
|
|
|
|
@pytest.mark.parametrize('hardware,named', [
|
|
({'row_address_type': 1}, 'row address type 1'),
|
|
({'row_address_type': 3}, 'row address type 3'),
|
|
({'row_address_type': 4}, 'row address type 4'),
|
|
({'row_address_type': '5'}, 'row address type 5'),
|
|
({'parallel': 4}, 'parallel 4'),
|
|
({'hardware_mapping': 'compute-module'}, 'hardware mapping "compute-module"'),
|
|
])
|
|
def test_what_it_does_not(hardware, named):
|
|
message = pi5.pi5_unsupported_settings(hardware)
|
|
assert message is not None and named in message
|
|
|
|
|
|
def test_every_problem_is_named():
|
|
message = pi5.pi5_unsupported_settings({'row_address_type': 5, 'parallel': 4})
|
|
assert 'row address type 5' in message and 'parallel 4' in message
|