Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
./*.pio.h
protodemo
./build
*.egg-info
8 changes: 7 additions & 1 deletion examples/playframes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import glob
import sys
import time

import adafruit_raspberry_pi5_piomatter
import numpy as np
Expand All @@ -20,10 +21,15 @@

geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=64, height=32, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
framebuffer = np.asarray(Image.open(images[0])) + 0 # Make a mutable copy
nimages = len(images)
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)

while True:
t0 = time.monotonic()
for i in images:
print(i)
framebuffer[:] = np.asarray(Image.open(i))
matrix.show()
t1 = time.monotonic()
dt = t1 - t0
fps = nimages/dt
print(f"{nimages} frames in {dt}s, {fps}fps")
49 changes: 28 additions & 21 deletions src/include/piomatter/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
namespace piomatter {

constexpr unsigned DATA_OVERHEAD = 3;
constexpr unsigned CLOCKS_PER_DATA = 2;
// this is ... flatly wrong!? but it's the number that makes the ramp intensity
// correct to my eye
constexpr unsigned CLOCKS_PER_DATA = 128;
constexpr unsigned DELAY_OVERHEAD = 5;
constexpr unsigned CLOCKS_PER_DELAY = 1;

Expand All @@ -18,7 +20,7 @@ constexpr uint32_t command_delay = 0;
struct gamma_lut {
gamma_lut(double exponent = 2.2) {
for (int i = 0; i < 256; i++) {
auto v = std::max(i, int(round(1023 * pow(i / 255, exponent))));
auto v = std::max(i, int(round(1023 * pow(i / 255., exponent))));
lut[i] = v;
}
}
Expand Down Expand Up @@ -159,10 +161,21 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
result.push_back(d);
};

auto do_data_delay = [&](uint32_t d, uint32_t delay) {
int32_t active_time;

auto do_data_active = [&active_time, &do_data](uint32_t d) {
bool active = active_time > 0;
active_time--;
d |= active ? pinout::oe_active : pinout::oe_inactive;
do_data(d);
};

auto do_data_delay = [&prep_data, &do_data, &do_delay](uint32_t d,
int32_t delay) {
prep_data(1);
do_data(d);
do_delay(delay);
if (delay > 0)
do_delay(delay);
};

auto calc_addr_bits = [](int addr) {
Expand All @@ -184,11 +197,10 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
return data;
};

auto add_pixels = [&do_data, &result](uint32_t addr_bits, bool r0, bool g0,
bool b0, bool r1, bool g1, bool b1,
bool active) {
uint32_t data =
(active ? pinout::oe_active : pinout::oe_inactive) | addr_bits;
auto add_pixels = [&do_data_active, &result](uint32_t addr_bits, bool r0,
bool g0, bool b0, bool r1,
bool g1, bool b1) {
uint32_t data = addr_bits;
if (r0)
data |= (1 << pinout::PIN_RGB[0]);
if (g0)
Expand All @@ -202,8 +214,8 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
if (b1)
data |= (1 << pinout::PIN_RGB[5]);

do_data(data);
do_data(data | pinout::clk_bit);
do_data_active(data);
do_data_active(data | pinout::clk_bit);
};

int last_bit = 0;
Expand All @@ -230,7 +242,7 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
// the shortest /OE we can do is one DATA_OVERHEAD...
// TODO: should make sure desired duration of MSB is at least
// `pixels_across`
uint32_t desired_duration = 1 << last_bit;
active_time = 1 << last_bit;
last_bit = bit;

prep_data(2 * pixels_across);
Expand All @@ -247,17 +259,12 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
auto g1 = pixel1 & g;
auto b1 = pixel1 & b;

add_pixels(addr_bits, r0, g0, b0, r1, g1, b1,
x < desired_duration);
add_pixels(addr_bits, r0, g0, b0, r1, g1, b1);
}

// hold /OE low until desired time has elapsed to illuminate the
// LAST line
int remain = desired_duration - pixels_across;
if (remain > 0) {
do_data_delay(addr_bits | pinout::oe_active,
remain * CLOCKS_PER_DATA - DELAY_OVERHEAD);
}
do_data_delay(addr_bits | pinout::oe_active,
active_time * CLOCKS_PER_DATA / CLOCKS_PER_DELAY -
DELAY_OVERHEAD);

do_data_delay(addr_bits | pinout::oe_inactive,
pinout::post_oe_delay);
Expand Down
Loading