@@ -247,6 +247,16 @@ LedDeviceWS2812b::LedDeviceWS2812b() :
247
247
// Init PWM generator and clear LED buffer
248
248
initHardware ();
249
249
// clearLEDBuffer();
250
+
251
+ // init bit pattern, it is always 1X0
252
+ unsigned int wireBit = 0 ;
253
+
254
+ while ((wireBit + 3 ) < ((NUM_DATA_WORDS) * 4 * 8 )){
255
+ setPWMBit (wireBit++, 1 );
256
+ setPWMBit (wireBit++, 0 ); // just init it with 0
257
+ setPWMBit (wireBit++, 0 );
258
+ }
259
+
250
260
printf (" WS2812b init finished \n " );
251
261
}
252
262
@@ -267,7 +277,7 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
267
277
268
278
// Read data from LEDBuffer[], translate it into wire format, and write to PWMWaveform
269
279
unsigned int colorBits = 0 ; // Holds the GRB color before conversion to wire bit pattern
270
- unsigned int wireBit = 0 ; // Holds the current bit we will set in PWMWaveform
280
+ unsigned int wireBit = 1 ; // Holds the current bit we will set in PWMWaveform, start with 1 and skip the other two for speed
271
281
272
282
// Copy PWM waveform to DMA's data buffer
273
283
// printf("Copying %d words to DMA data buffer\n", NUM_DATA_WORDS);
@@ -277,12 +287,16 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
277
287
// 72 bits per pixel / 32 bits per word = 2.25 words per pixel
278
288
// Add 1 to make sure the PWM FIFO gets the message: "we're sending zeroes"
279
289
// Times 4 because DMA works in bytes, not words
280
- cbp->length = ((mLedCount * 2.25 ) + 1 ) * 4 ;
290
+ cbp->length = (mLedCount * 2.25 ) * 4 ;
291
+ // cbp->length = ((mLedCount * 2.25) + 1) * 4;
281
292
if (cbp->length > NUM_DATA_WORDS * 4 ) {
282
293
cbp->length = NUM_DATA_WORDS * 4 ;
283
- mLedCount = (NUM_DATA_WORDS - 1 ) / 2.25 ;
294
+ mLedCount = NUM_DATA_WORDS / 2.25 ;
295
+ // mLedCount = (NUM_DATA_WORDS - 1) / 2.25;
284
296
}
285
297
298
+
299
+
286
300
for (size_t i=0 ; i<mLedCount ; i++) {
287
301
// Create bits necessary to represent one color triplet (in GRB, not RGB, order)
288
302
// printf("RGB: %d, %d, %d\n", ledValues[i].red, ledValues[i].green, ledValues[i].blue);
@@ -294,9 +308,8 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
294
308
for (int j=23 ; j>=0 ; j--) {
295
309
unsigned char colorBit = (colorBits & (1 << j)) ? 1 : 0 ; // Holds current bit out of colorBits to be processed
296
310
297
- setPWMBit (wireBit++, 1 );
298
- setPWMBit (wireBit++, colorBit);
299
- setPWMBit (wireBit++, 0 );
311
+ setPWMBit (wireBit, colorBit);
312
+ wireBit +=3 ;
300
313
/* old code for better understanding
301
314
switch(colorBit) {
302
315
case 1:
@@ -315,6 +328,25 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
315
328
}
316
329
}
317
330
331
+ // remove one to undo optimization
332
+ wireBit --;
333
+
334
+ // fill up the bytes
335
+ int rest = 32 - wireBit % 32 ;
336
+ unsigned int oldwireBitValue = wireBit;
337
+
338
+ // printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
339
+ // printf(" pre\n");
340
+
341
+ // zero rest of the 4 bytes / int so that output is 0 (no data is send)
342
+ for (int i = 0 ; i < rest; i += 3 ){
343
+ setPWMBit (wireBit, 0 );
344
+ wireBit += 3 ;
345
+ }
346
+
347
+ // printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
348
+ // printf(" post\n");
349
+
318
350
// This block is a major CPU hog when there are lots of pixels to be transmitted.
319
351
// It would go quicker with DMA.
320
352
// for(unsigned int i = 0; i < (cbp->length / 4); i++) {
@@ -325,6 +357,16 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
325
357
// Enable DMA and PWM engines, which should now send the data
326
358
startTransfer ();
327
359
360
+ // restore bit pattern
361
+ wireBit = oldwireBitValue;
362
+ for (int i = 0 ; i < rest; i += 3 ){
363
+ setPWMBit (wireBit, 1 );
364
+ wireBit += 3 ;
365
+ }
366
+
367
+ // printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
368
+ // printf(" restored\n");
369
+
328
370
// Wait long enough for the DMA transfer to finish
329
371
// 3 RAM bits per wire bit, so 72 bits to send one color command.
330
372
// float bitTimeUSec = (float)(NUM_DATA_WORDS * 32) * 0.4; // Bits sent * time to transmit one bit, which is 0.4μSec
0 commit comments