Add portal web simulator, SPI bridges, and Pico firmware updates.
Bring the five-panel hex portal online with a browser 3D/schematic preview, Pi SPI backends, and renamed multi-panel Pico UDP firmware. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
54
leds/backends/rpi5_ws2812.py
Normal file
54
leds/backends/rpi5_ws2812.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""WS2812 over SPI via the rpi5-ws2812 package (Pi 5, GPIO 10)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
from rpi5_ws2812.ws2812 import WS2812SpiDriver
|
||||
|
||||
from leds.backends.spi import spidev_bufsize_hint
|
||||
|
||||
|
||||
class Rpi5Ws2812Backend:
|
||||
def __init__(
|
||||
self,
|
||||
led_count: int,
|
||||
*,
|
||||
spi_bus: int = 0,
|
||||
spi_device: int = 0,
|
||||
max_speed_hz: int = 4_200_000,
|
||||
) -> None:
|
||||
hint = spidev_bufsize_hint(led_count)
|
||||
if hint:
|
||||
raise OSError(hint)
|
||||
|
||||
self._led_count = led_count
|
||||
self._driver = WS2812SpiDriver(spi_bus, spi_device, led_count)
|
||||
self._driver._device.max_speed_hz = max_speed_hz
|
||||
|
||||
@property
|
||||
def led_count(self) -> int:
|
||||
return self._led_count
|
||||
|
||||
def write_grb(self, rgb_bytes: bytes) -> None:
|
||||
"""RGB bytes passed through to SPI unchanged."""
|
||||
if len(rgb_bytes) != self._led_count * 3:
|
||||
raise ValueError(
|
||||
f"expected {self._led_count * 3} bytes, got {len(rgb_bytes)}"
|
||||
)
|
||||
buf = np.frombuffer(rgb_bytes, dtype=np.uint8).reshape(self._led_count, 3)
|
||||
self._driver.write(buf)
|
||||
|
||||
def clear(self) -> None:
|
||||
self._driver.clear()
|
||||
|
||||
def close(self) -> None:
|
||||
try:
|
||||
self.clear()
|
||||
finally:
|
||||
self._driver._device.close()
|
||||
|
||||
def __enter__(self) -> Rpi5Ws2812Backend:
|
||||
return self
|
||||
|
||||
def __exit__(self, *_exc) -> None:
|
||||
self.close()
|
||||
Reference in New Issue
Block a user