diff --git a/examples/fbmirror.py b/examples/fbmirror.py index 99bd3b4..d6a670d 100644 --- a/examples/fbmirror.py +++ b/examples/fbmirror.py @@ -17,6 +17,7 @@ import numpy as np import adafruit_blinka_raspberry_pi5_piomatter as piomatter import adafruit_blinka_raspberry_pi5_piomatter.click as piomatter_click +from adafruit_blinka_raspberry_pi5_piomatter.pixelmappers import simple_multilane_mapper with open("/sys/class/graphics/fb0/virtual_size") as f: screenx, screeny = [int(word) for word in f.read().split(",")] @@ -55,7 +56,7 @@ def make_pixelmap_multilane(width, height, n_addr_lines, n_lanes): @piomatter_click.standard_options(n_lanes=2, n_temporal_planes=4) def main(xoffset, yoffset, width, height, serpentine, rotation, pinout, n_planes, n_temporal_planes, n_addr_lines, n_lanes): if n_lanes != 2: - pixelmap = make_pixelmap_multilane(width, height, n_addr_lines, n_lanes) + pixelmap = simple_multilane_mapper(width, height, n_addr_lines, n_lanes) geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, n_temporal_planes=n_temporal_planes, n_lanes=n_lanes, map=pixelmap) else: geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, n_temporal_planes=n_temporal_planes, rotation=rotation) diff --git a/examples/rainbow_spiral_active3.py b/examples/rainbow_spiral_active3.py index 941fb96..555c40f 100644 --- a/examples/rainbow_spiral_active3.py +++ b/examples/rainbow_spiral_active3.py @@ -15,6 +15,7 @@ import rainbowio from PIL import Image, ImageDraw import adafruit_blinka_raspberry_pi5_piomatter as piomatter +from adafruit_blinka_raspberry_pi5_piomatter.pixelmappers import simple_multilane_mapper width = 64 n_lanes = 6 @@ -22,25 +23,10 @@ n_addr_lines = 5 height = n_lanes << n_addr_lines pen_radius = 1 -def make_pixelmap_multilane(width, height, n_addr_lines, n_lanes): - calc_height = n_lanes << n_addr_lines - if height != calc_height: - raise RuntimeError(f"Calculated height {calc_height} does not match requested height {height}") - n_addr = 1 << n_addr_lines - - m = [] - for addr in range(n_addr): - for x in range(width): - for lane in range(n_lanes): - y = addr + lane * n_addr - m.append(x + width * y) - return m - - canvas = Image.new('RGB', (width, height), (0, 0, 0)) draw = ImageDraw.Draw(canvas) -pixelmap = make_pixelmap_multilane(width, height, n_addr_lines, n_lanes) +pixelmap = simple_multilane_mapper(width, height, n_addr_lines, n_lanes) geometry = piomatter.Geometry(width=width, height=height, n_addr_lines=n_addr_lines, n_planes=10, n_temporal_planes=4, map=pixelmap, n_lanes=n_lanes) framebuffer = np.asarray(canvas) + 0 # Make a mutable copy matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed, diff --git a/pyproject.toml b/pyproject.toml index adf1357..f90c314 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,5 +18,6 @@ lint.extend-select = [ ] lint.extend-ignore = [ "E501", # Line too long + "RUF002", # Yes I meant to type 'multiplication sign'! ] target-version = "py311" diff --git a/src/adafruit_blinka_raspberry_pi5_piomatter/pixelmappers.py b/src/adafruit_blinka_raspberry_pi5_piomatter/pixelmappers.py new file mode 100644 index 0000000..70877b2 --- /dev/null +++ b/src/adafruit_blinka_raspberry_pi5_piomatter/pixelmappers.py @@ -0,0 +1,29 @@ +def simple_multilane_mapper(width, height, n_addr_lines, n_lanes): + """A simple mapper for 4+ pixel lanes + + A framebuffer (width × height) is mapped onto a matrix where the lanes are stacked + top-to-bottom. Panels within a lane may be cascaded left-to-right. + + Rotation is not supported, and neither are more complicated arrangements of panels + within a single chain (no support for serpentine or stacked panels within a segment) + + .. code-block:: raw + + 0 -> [panel] -> [panel] + 1 -> [panel] -> [panel] + 2 -> [panel] -> [panel] + """ + + calc_height = n_lanes << n_addr_lines + if height != calc_height: + raise RuntimeError(f"Calculated height {calc_height} does not match requested height {height}") + n_addr = 1 << n_addr_lines + + m = [] + for addr in range(n_addr): + for x in range(width): + for lane in range(n_lanes): + y = addr + lane * n_addr + m.append(x + width * y) + print(m) + return m