hzeller / rpi-rgb-led-matrix

Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO
GNU General Public License v2.0
3.57k stars 1.14k forks source link

supporting panels of with broken color orders in the middle of a chain. #1672

Open marcmerlin opened 3 days ago

marcmerlin commented 3 days ago

I arranged things so that the broken color panels were together, although with the mapping code they can be anywhere image

After the dirty patch, it's all fixed now. Just to be clear, you can't use the command line argument to remap colors since it's global, but thankfully it's actually not hard to remap on a per area or even per panel basis if needed. image

diff --git a/lib/framebuffer.cc b/lib/framebuffer.cc
index e7cc98f..77aeb8e 100644
--- a/lib/framebuffer.cc
+++ b/lib/framebuffer.cc
@@ -313,6 +313,7 @@ Framebuffer::Framebuffer(int rows, int columns, int parallel,
   }
   assert(parallel >= 1 && parallel <= 3);

+  printf("Color Fixing Patch Present for GFXDISPLAY_M288BY192_9_3_Zmap\n");
   bitplane_buffer_ = new gpio_bits_t[double_rows_ * columns_ * kBitPlanes];

   // If we're the first Framebuffer created, the shared PixelMapper is
@@ -341,6 +342,7 @@ Framebuffer::Framebuffer(int rows, int columns, int parallel,
         InitDefaultDesignator(x, y, led_sequence, (*shared_mapper_)->get(x, y));
       }
     }
+    printf(">>> Color Fixing Patch Applied for GFXDISPLAY_M288BY192_9_3_Zmap <<<\n");
   }

   Clear();
@@ -701,38 +701,76 @@ void Framebuffer::InitDefaultDesignator(int x, int y, const char *seq,
   uint32_t *bits = ValueAt(y % double_rows_, x, 0);
   d->gpio_word = bits - bitplane_buffer_;
   d->r_bit = d->g_bit = d->b_bit = 0;
-  if (y < rows_) {
-    if (y < double_rows_) {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p0_r1, h.p0_g1, h.p0_b1);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p0_r1, h.p0_g1, h.p0_b1);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p0_r1, h.p0_g1, h.p0_b1);
-    } else {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p0_r2, h.p0_g2, h.p0_b2);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p0_r2, h.p0_g2, h.p0_b2);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p0_r2, h.p0_g2, h.p0_b2);
-    }
-  }
-  else if (y >= rows_ && y < 2 * rows_) {
-    if (y - rows_ < double_rows_) {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p1_r1, h.p1_g1, h.p1_b1);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p1_r1, h.p1_g1, h.p1_b1);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p1_r1, h.p1_g1, h.p1_b1);
-    } else {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p1_r2, h.p1_g2, h.p1_b2);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p1_r2, h.p1_g2, h.p1_b2);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p1_r2, h.p1_g2, h.p1_b2);
-    }
-  }
-  else {
-    if (y - 2*rows_ < double_rows_) {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p2_r1, h.p2_g1, h.p2_b1);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p2_r1, h.p2_g1, h.p2_b1);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p2_r1, h.p2_g1, h.p2_b1);
-    } else {
-      d->r_bit = GetGpioFromLedSequence('R', seq, h.p2_r2, h.p2_g2, h.p2_b2);
-      d->g_bit = GetGpioFromLedSequence('G', seq, h.p2_r2, h.p2_g2, h.p2_b2);
-      d->b_bit = GetGpioFromLedSequence('B', seq, h.p2_r2, h.p2_g2, h.p2_b2);
-    }
+ // Note that line order may be backwards from what you think. To fix the bottom lines closest to
+ // cable pixel injection, it's actually the last lines of the matrix, not the first ones.
+  if (x >= 384) {
+          // printf("fixed: %d : %d \n", x,  y);
+     if (y < rows_) {
+       if (y < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+       }
+     }
+     else if (y >= rows_ && y < 2 * rows_) {
+       if (y - rows_ < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+       }
+     }
+     else {
+       if (y - 2*rows_ < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('G', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+         d->g_bit = GetGpioFromLedSequence('B', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+         d->b_bit = GetGpioFromLedSequence('R', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+       }
+     }
+   } else { 
+          //printf("orig: %d : %d \n", x,  y);
+     if (y < rows_) {
+       if (y < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p0_r1, h.p0_g1, h.p0_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p0_r2, h.p0_g2, h.p0_b2);
+       }
+     }
+     else if (y >= rows_ && y < 2 * rows_) {
+       if (y - rows_ < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p1_r1, h.p1_g1, h.p1_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p1_r2, h.p1_g2, h.p1_b2);
+       }
+     }
+     else {
+       if (y - 2*rows_ < double_rows_) {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p2_r1, h.p2_g1, h.p2_b1);
+       } else {
+         d->r_bit = GetGpioFromLedSequence('R', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+         d->g_bit = GetGpioFromLedSequence('G', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+         d->b_bit = GetGpioFromLedSequence('B', seq, h.p2_r2, h.p2_g2, h.p2_b2);
+       }
+     }
   }

   d->mask = ~(d->r_bit | d->g_bit | d->b_bit);
marcmerlin commented 3 days ago

I'm only leaving this as an issue for archiving and later reference, it's definitely a dirty patch directly in the code, but it shows that function can be used to remap the colors of any pixel on any panel, which is cool @hzeller you can close this or leave open at your leisure