From 39bc663b26d55d4f0c8e7cf320f6e8c5b76230db Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 9 Mar 2025 13:45:53 -0500 Subject: [PATCH] introduce pixel schedules --- src/include/piomatter/matrixmap.h | 31 ++++++++++++++++++++++--- src/include/piomatter/protomatter.pio.h | 2 +- src/include/piomatter/render.h | 22 ++++++------------ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/include/piomatter/matrixmap.h b/src/include/piomatter/matrixmap.h index 98b184d..47885f1 100644 --- a/src/include/piomatter/matrixmap.h +++ b/src/include/piomatter/matrixmap.h @@ -81,6 +81,24 @@ matrix_map make_matrixmap(size_t width, size_t height, size_t n_addr_lines, return result; } +struct schedule_entry { + uint32_t shift, active_time; +}; + +using schedule = std::vector; + +schedule make_simple_schedule(int n_planes, int pixels_across) { + schedule result; + uint32_t max_count = 1 << n_planes; + while (max_count < pixels_across) + max_count <<= 1; + + for (int i = 0; i < n_planes; i++) { + result.emplace_back(10 - i, max_count >> i); + } + return result; +} + struct matrix_geometry { template matrix_geometry(size_t pixels_across, size_t n_addr_lines, int n_planes, @@ -91,9 +109,16 @@ struct matrix_geometry { matrix_geometry(size_t pixels_across, size_t n_addr_lines, int n_planes, size_t width, size_t height, matrix_map map, size_t n_lanes) + : matrix_geometry(pixels_across, n_addr_lines, width, height, map, + n_lanes, + make_simple_schedule(n_planes, pixels_across)) {} + + matrix_geometry(size_t pixels_across, size_t n_addr_lines, size_t width, + size_t height, matrix_map map, size_t n_lanes, + const std::vector schedule) : pixels_across(pixels_across), n_addr_lines(n_addr_lines), - n_lanes(n_lanes), n_planes(n_planes), width(width), height(height), - map(map) { + n_lanes(n_lanes), width(width), height(height), + map(map), schedule{schedule} { size_t pixels_down = n_lanes << n_addr_lines; if (map.size() != pixels_down * pixels_across) { throw std::range_error( @@ -102,7 +127,7 @@ struct matrix_geometry { } size_t pixels_across, n_addr_lines, n_lanes; - int n_planes; + std::vector schedule; size_t width, height; matrix_map map; }; diff --git a/src/include/piomatter/protomatter.pio.h b/src/include/piomatter/protomatter.pio.h index 73485e2..ee5e74a 100644 --- a/src/include/piomatter/protomatter.pio.h +++ b/src/include/piomatter/protomatter.pio.h @@ -3,7 +3,7 @@ const int protomatter_wrap = 4; const int protomatter_wrap_target = 0; const int protomatter_sideset_pin_count = 1; -const bool protomatter_sideset_enable = true; +const bool protomatter_sideset_enable = 1; const uint16_t protomatter[] = { // ; data format (out-shift-right): // ; MSB ... LSB diff --git a/src/include/piomatter/render.h b/src/include/piomatter/render.h index 59ae2d1..c8bc059 100644 --- a/src/include/piomatter/render.h +++ b/src/include/piomatter/render.h @@ -183,32 +183,22 @@ void protomatter_render_rgb10(std::vector &result, return data; }; - int last_bit = 0; // illuminate the right row for data in the shift register (the previous // address) const size_t n_addr = 1u << matrixmap.n_addr_lines; - const int n_planes = matrixmap.n_planes; constexpr size_t n_bits = 10u; - unsigned offset = n_bits - n_planes; const size_t pixels_across = matrixmap.pixels_across; size_t prev_addr = n_addr - 1; uint32_t addr_bits = calc_addr_bits(prev_addr); for (size_t addr = 0; addr < n_addr; addr++) { - // printf("addr=%zu/%zu\n", addr, n_addr); - for (int bit = n_planes - 1; bit >= 0; bit--) { - // printf("bit=%d/%d\n", bit, n_planes); - uint32_t r_mask = 1 << (20 + offset + bit); - uint32_t g_mask = 1 << (10 + offset + bit); - uint32_t b_mask = 1 << (0 + offset + bit); - - // the shortest /OE we can do is one DATA_OVERHEAD... - // TODO: should make sure desired duration of MSB is at least - // `pixels_across` - active_time = 1 << last_bit; - last_bit = bit; + uint32_t active_time = matrixmap.schedule.back().active_time; + for (auto &schedule_ent : matrixmap.schedule) { + uint32_t r_mask = 1 << (20 + schedule_ent.shift); + uint32_t g_mask = 1 << (10 + schedule_ent.shift); + uint32_t b_mask = 1 << (0 + schedule_ent.shift); prep_data(pixels_across); auto mapiter = matrixmap.map.begin() + @@ -242,6 +232,8 @@ void protomatter_render_rgb10(std::vector &result, do_data_delay(addr_bits | pinout::oe_inactive | pinout::lat_bit, pinout::post_latch_delay); + active_time = schedule_ent.active_time; + // with oe inactive, set address bits to illuminate THIS line if (addr != prev_addr) { addr_bits = calc_addr_bits(addr);