From f3819c84ebb3fc951e9b39f56422e969d5507e30 Mon Sep 17 00:00:00 2001 From: Puck Meerburg Date: Mon, 23 Feb 2026 18:49:26 +0000 Subject: [PATCH] led: improve row_buf calculation --- src/led.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/led.c b/src/led.c index bd807ef..2875ec1 100644 --- a/src/led.c +++ b/src/led.c @@ -70,8 +70,8 @@ void display_make_buf(uint16_t *fb, struct row_buf *b, int i) { b->pb_out = 0; b->pb_drv = 0; - uint16_t col1 = fb[i * 2]; - uint16_t col2 = fb[i * 2 + 1]; + uint32_t col1 = fb[i * 2]; + uint32_t col2 = fb[i * 2 + 1]; #if NEEDS_SWAP // On the first column, the lower two pins are swapped. Fix this in software. @@ -83,17 +83,22 @@ void display_make_buf(uint16_t *fb, struct row_buf *b, int i) { #endif // The LEDs are written in a zig-zag pattern. - uint32_t merged = 0; - merged |= ((col1 & 1) << 22); - merged |= ((col2 & 1) << 23); - for (int j = 0; j < 11; j++) { - col1 >>= 1; - col2 >>= 1; + // + // The two rows are zippered together; use a slightly + // optimized trick for this. - merged >>= 2; - merged |= (col1 & 1) << 22; - merged |= (col2 & 1) << 23; - } + // We start off with 0b123456789ab + col1 = (col1 | (col1 << 8)) & 0x00FF00FF; // 0b------12--------456789ab + col2 = (col2 | (col2 << 8)) & 0x00FF00FF; + col1 = (col1 | (col1 << 4)) & 0x0F0F0F0F; // 0b------12----4567----89ab + col2 = (col2 | (col2 << 4)) & 0x0F0F0F0F; + col1 = (col1 | (col1 << 2)) & 0x33333333; + col2 = (col2 | (col2 << 2)) & 0x33333333; // 0b------12--45--67--89--ab + col1 = (col1 | (col1 << 1)) & 0x55555555; + col2 = (col2 | (col2 << 1)) & 0x55555555; // 0b-----1-2-4-5-6-7-8-9-a-b + + // Zip col1 and col2 together. + uint32_t merged = col1 | (col2 << 1); // In this LED matrix, we set row N as a high output, // then set all other lines to tristate or low, depending