88namespace  piomatter  {
99
1010constexpr  unsigned  DATA_OVERHEAD = 3 ;
11- constexpr  unsigned  CLOCKS_PER_DATA = 2 ;
11+ //  this is ... flatly wrong!? but it's the number that makes the ramp intensity
12+ //  correct to my eye
13+ constexpr  unsigned  CLOCKS_PER_DATA = 128 ;
1214constexpr  unsigned  DELAY_OVERHEAD = 5 ;
1315constexpr  unsigned  CLOCKS_PER_DELAY = 1 ;
1416
@@ -18,7 +20,7 @@ constexpr uint32_t command_delay = 0;
1820struct  gamma_lut  {
1921    gamma_lut (double  exponent = 2.2 ) {
2022        for  (int  i = 0 ; i < 256 ; i++) {
21-             auto  v = std::max (i, int (round (1023  * pow (i / 255 , exponent))));
23+             auto  v = std::max (i, int (round (1023  * pow (i / 255 . , exponent))));
2224            lut[i] = v;
2325        }
2426    }
@@ -159,10 +161,21 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
159161        result.push_back (d);
160162    };
161163
162-     auto  do_data_delay = [&](uint32_t  d, uint32_t  delay) {
164+     int32_t  active_time;
165+ 
166+     auto  do_data_active = [&active_time, &do_data](uint32_t  d) {
167+         bool  active = active_time > 0 ;
168+         active_time--;
169+         d |= active ? pinout::oe_active : pinout::oe_inactive;
170+         do_data (d);
171+     };
172+ 
173+     auto  do_data_delay = [&prep_data, &do_data, &do_delay](uint32_t  d,
174+                                                            int32_t  delay) {
163175        prep_data (1 );
164176        do_data (d);
165-         do_delay (delay);
177+         if  (delay > 0 )
178+             do_delay (delay);
166179    };
167180
168181    auto  calc_addr_bits = [](int  addr) {
@@ -184,11 +197,10 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
184197        return  data;
185198    };
186199
187-     auto  add_pixels = [&do_data, &result](uint32_t  addr_bits, bool  r0, bool  g0,
188-                                           bool  b0, bool  r1, bool  g1, bool  b1,
189-                                           bool  active) {
190-         uint32_t  data =
191-             (active ? pinout::oe_active : pinout::oe_inactive) | addr_bits;
200+     auto  add_pixels = [&do_data_active, &result](uint32_t  addr_bits, bool  r0,
201+                                                  bool  g0, bool  b0, bool  r1,
202+                                                  bool  g1, bool  b1) {
203+         uint32_t  data = addr_bits;
192204        if  (r0)
193205            data |= (1  << pinout::PIN_RGB[0 ]);
194206        if  (g0)
@@ -202,8 +214,8 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
202214        if  (b1)
203215            data |= (1  << pinout::PIN_RGB[5 ]);
204216
205-         do_data (data);
206-         do_data (data | pinout::clk_bit);
217+         do_data_active (data);
218+         do_data_active (data | pinout::clk_bit);
207219    };
208220
209221    int  last_bit = 0 ;
@@ -230,7 +242,7 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
230242            //  the shortest /OE we can do is one DATA_OVERHEAD...
231243            //  TODO: should make sure desired duration of MSB is at least
232244            //  `pixels_across`
233-             uint32_t  desired_duration  = 1  << last_bit;
245+             active_time  = 1  << last_bit;
234246            last_bit = bit;
235247
236248            prep_data (2  * pixels_across);
@@ -247,17 +259,12 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
247259                auto  g1 = pixel1 & g;
248260                auto  b1 = pixel1 & b;
249261
250-                 add_pixels (addr_bits, r0, g0, b0, r1, g1, b1,
251-                            x < desired_duration);
262+                 add_pixels (addr_bits, r0, g0, b0, r1, g1, b1);
252263            }
253264
254-             //  hold /OE low until desired time has elapsed to illuminate the
255-             //  LAST line
256-             int  remain = desired_duration - pixels_across;
257-             if  (remain > 0 ) {
258-                 do_data_delay (addr_bits | pinout::oe_active,
259-                               remain * CLOCKS_PER_DATA - DELAY_OVERHEAD);
260-             }
265+             do_data_delay (addr_bits | pinout::oe_active,
266+                           active_time * CLOCKS_PER_DATA / CLOCKS_PER_DELAY -
267+                               DELAY_OVERHEAD);
261268
262269            do_data_delay (addr_bits | pinout::oe_inactive,
263270                          pinout::post_oe_delay);
0 commit comments