Add multi-panel Pico UDP firmware and Python LED control.
Pico panels get static IPs on 10.1.1.10–14 with per-panel LED counts, Makefile deploy targets, and Python examples for animations, sync tests, and direct Pi SPI control. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
151
leds/config.py
Normal file
151
leds/config.py
Normal file
@@ -0,0 +1,151 @@
|
||||
"""Default wiring for one or two WS2812 strips per board."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
from leds.detect import board_family, pio_available, pio_device, pi5_second_spi_bus
|
||||
|
||||
try:
|
||||
from leds.array_config import MATRIX_SPI_BUS, MATRIX_SPI_DEVICE
|
||||
except ImportError:
|
||||
MATRIX_SPI_BUS = 0
|
||||
MATRIX_SPI_DEVICE = 0
|
||||
|
||||
BackendName = Literal["auto", "pio", "spi", "ws281x"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class StripConfig:
|
||||
count: int
|
||||
backend: BackendName = "auto"
|
||||
pin: int = 18
|
||||
channel: int = 0
|
||||
device: str = "/dev/leds0"
|
||||
spi_bus: int = 0
|
||||
spi_device: int = 0
|
||||
brightness: float = 1.0
|
||||
|
||||
|
||||
def spi_strip_config(
|
||||
count: int,
|
||||
*,
|
||||
spi_bus: int = MATRIX_SPI_BUS,
|
||||
spi_device: int = MATRIX_SPI_DEVICE,
|
||||
brightness: float = 1.0,
|
||||
) -> StripConfig:
|
||||
return StripConfig(
|
||||
count,
|
||||
backend="spi",
|
||||
spi_bus=spi_bus,
|
||||
spi_device=spi_device,
|
||||
brightness=brightness,
|
||||
)
|
||||
|
||||
|
||||
def default_strip_config(count: int, *, brightness: float = 1.0) -> StripConfig:
|
||||
family = board_family()
|
||||
if family == "pi5":
|
||||
if pio_available():
|
||||
return StripConfig(
|
||||
count,
|
||||
backend="pio",
|
||||
pin=18,
|
||||
device=pio_device(0) or "/dev/leds0",
|
||||
brightness=brightness,
|
||||
)
|
||||
return spi_strip_config(count, brightness=brightness)
|
||||
return StripConfig(
|
||||
count,
|
||||
backend="ws281x",
|
||||
pin=18,
|
||||
channel=0,
|
||||
brightness=brightness,
|
||||
)
|
||||
|
||||
|
||||
def default_dual_strip_configs(
|
||||
count0: int,
|
||||
count1: int,
|
||||
*,
|
||||
brightness: float = 1.0,
|
||||
) -> tuple[StripConfig, StripConfig]:
|
||||
"""
|
||||
Suggested wiring for two independent strips:
|
||||
|
||||
Pi 5 (SPI — requires dtoverlay=spi1-3cs under [all], not [cm5]):
|
||||
strip 0 → GPIO 10 (SPI0 MOSI), /dev/spidev0.0
|
||||
strip 1 → GPIO 20 (SPI1 MOSI), /dev/spidev1.0
|
||||
|
||||
Pi 5 (ws2812-pio — alternative):
|
||||
strip 0 → GPIO 18, /dev/leds0
|
||||
strip 1 → GPIO 13, /dev/leds1
|
||||
|
||||
Pi 4 / Zero:
|
||||
strip 0 → GPIO 18 (PWM channel 0)
|
||||
strip 1 → GPIO 13 (PWM channel 1)
|
||||
"""
|
||||
family = board_family()
|
||||
if family == "pi5":
|
||||
if pio_available():
|
||||
return (
|
||||
StripConfig(
|
||||
count0,
|
||||
backend="pio",
|
||||
pin=18,
|
||||
device=pio_device(0) or "/dev/leds0",
|
||||
brightness=brightness,
|
||||
),
|
||||
StripConfig(
|
||||
count1,
|
||||
backend="pio",
|
||||
pin=13,
|
||||
device=pio_device(1) or "/dev/leds1",
|
||||
brightness=brightness,
|
||||
),
|
||||
)
|
||||
return (
|
||||
StripConfig(
|
||||
count0,
|
||||
backend="spi",
|
||||
spi_bus=0,
|
||||
spi_device=0,
|
||||
brightness=brightness,
|
||||
),
|
||||
StripConfig(
|
||||
count1,
|
||||
backend="spi",
|
||||
spi_bus=pi5_second_spi_bus(),
|
||||
spi_device=0,
|
||||
brightness=brightness,
|
||||
),
|
||||
)
|
||||
|
||||
return (
|
||||
StripConfig(
|
||||
count0,
|
||||
backend="ws281x",
|
||||
pin=18,
|
||||
channel=0,
|
||||
brightness=brightness,
|
||||
),
|
||||
StripConfig(
|
||||
count1,
|
||||
backend="ws281x",
|
||||
pin=13,
|
||||
channel=1,
|
||||
brightness=brightness,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def pi5_setup_hint(count0: int, count1: int) -> str:
|
||||
return (
|
||||
"Pi 5 second SPI bus not found. Add under [all] in /boot/firmware/config.txt:\n"
|
||||
" dtparam=spi=on\n"
|
||||
" dtoverlay=spi1-3cs\n"
|
||||
"Remove dtparam=spi1=on (ignored on Pi 5). Do not put the overlay under [cm5]\n"
|
||||
"unless you have a Compute Module 5.\n"
|
||||
"Wire strip 0 DIN → GPIO 10, strip 1 DIN → GPIO 20, then reboot."
|
||||
)
|
||||
Reference in New Issue
Block a user