From 9bd7813dc3d77a56e744e711b8d727dbda16f329 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 10 Mar 2025 09:53:34 -0500 Subject: [PATCH] Add rudimentary multi-connector support to fbmirror as well --- examples/fbmirror.py | 25 ++++++++++++++++--- .../click.py | 10 +++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/examples/fbmirror.py b/examples/fbmirror.py index 1fa64ac..99bd3b4 100644 --- a/examples/fbmirror.py +++ b/examples/fbmirror.py @@ -34,12 +34,31 @@ with open("/sys/class/graphics/fb0/stride") as f: linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype) +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) + print(m) + return m + @click.command @click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0) @click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0) -@piomatter_click.standard_options -def main(xoffset, yoffset, width, height, serpentine, rotation, pinout, n_planes, n_addr_lines): - geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, rotation=rotation) +@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) + 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) framebuffer = np.zeros(shape=(geometry.height, geometry.width), dtype=dtype) matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB565, pinout=pinout, framebuffer=framebuffer, geometry=geometry) diff --git a/src/adafruit_blinka_raspberry_pi5_piomatter/click.py b/src/adafruit_blinka_raspberry_pi5_piomatter/click.py index fdb39fc..aa1da77 100644 --- a/src/adafruit_blinka_raspberry_pi5_piomatter/click.py +++ b/src/adafruit_blinka_raspberry_pi5_piomatter/click.py @@ -26,6 +26,11 @@ class PybindEnumChoice(click.Choice): r = getattr(self.enum, value) return r +def validate_temporal_planes(ctx, param, value): + if value not in (0, 2, 4): + raise click.BadParameter("must be 0, 2, or 4") + return value + def standard_options( f: click.decorators.FC | None = None, *, @@ -35,6 +40,7 @@ def standard_options( rotation=piomatter.Orientation.Normal, pinout=piomatter.Pinout.AdafruitMatrixBonnet, n_planes=10, + n_temporal_planes=None, n_addr_lines=4, n_lanes=None, ) -> Callable[[], None]: @@ -75,7 +81,9 @@ def standard_options( help="The overall orientation (rotation) of the panels" )(f) if n_planes is not None: - f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth. Lower values can improve refresh rate in frames per second")(f) + f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth). Lower values can improve refresh rate in frames per second")(f) + if n_temporal_planes is not None: + f = click.option("--num-temporal-planes", "n_temporal_planes", default=n_temporal_planes, callback=validate_temporal_planes, help="The number of temporal bit-planes. May be 0, 2, or 4. Nonzero values improve frame rate but can cause some shimmer")(f) if n_addr_lines is not None: f = click.option("--num-address-lines", "n_addr_lines", default=n_addr_lines, help="The number of address lines used by the panels")(f) if n_lanes is not None: