Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit 08dc5ee

Browse files
committed
Pre initialized bit pattern to speed things up
1 parent 2c9ea90 commit 08dc5ee

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

libsrc/leddevice/LedDeviceWS2812b.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,16 @@ LedDeviceWS2812b::LedDeviceWS2812b() :
247247
// Init PWM generator and clear LED buffer
248248
initHardware();
249249
//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+
250260
printf("WS2812b init finished \n");
251261
}
252262

@@ -267,7 +277,7 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
267277

268278
// Read data from LEDBuffer[], translate it into wire format, and write to PWMWaveform
269279
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
271281

272282
// Copy PWM waveform to DMA's data buffer
273283
//printf("Copying %d words to DMA data buffer\n", NUM_DATA_WORDS);
@@ -277,12 +287,16 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
277287
// 72 bits per pixel / 32 bits per word = 2.25 words per pixel
278288
// Add 1 to make sure the PWM FIFO gets the message: "we're sending zeroes"
279289
// 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;
281292
if(cbp->length > NUM_DATA_WORDS * 4) {
282293
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;
284296
}
285297

298+
299+
286300
for(size_t i=0; i<mLedCount; i++) {
287301
// Create bits necessary to represent one color triplet (in GRB, not RGB, order)
288302
//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)
294308
for(int j=23; j>=0; j--) {
295309
unsigned char colorBit = (colorBits & (1 << j)) ? 1 : 0; // Holds current bit out of colorBits to be processed
296310

297-
setPWMBit(wireBit++, 1);
298-
setPWMBit(wireBit++, colorBit);
299-
setPWMBit(wireBit++, 0);
311+
setPWMBit(wireBit, colorBit);
312+
wireBit +=3;
300313
/* old code for better understanding
301314
switch(colorBit) {
302315
case 1:
@@ -315,6 +328,25 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
315328
}
316329
}
317330

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+
318350
// This block is a major CPU hog when there are lots of pixels to be transmitted.
319351
// It would go quicker with DMA.
320352
// for(unsigned int i = 0; i < (cbp->length / 4); i++) {
@@ -325,6 +357,16 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
325357
// Enable DMA and PWM engines, which should now send the data
326358
startTransfer();
327359

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+
328370
// Wait long enough for the DMA transfer to finish
329371
// 3 RAM bits per wire bit, so 72 bits to send one color command.
330372
//float bitTimeUSec = (float)(NUM_DATA_WORDS * 32) * 0.4; // Bits sent * time to transmit one bit, which is 0.4μSec

libsrc/leddevice/LedDeviceWS2812b.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
// Hyperion includes
102102
#include <leddevice/LedDevice.h>
103103

104-
//#define BENCHMARK
104+
#define BENCHMARK
105105

106106
// The page map contains pointers to memory that we will allocate below. It uses two pointers
107107
// per address. This is because the software (this program) deals only in virtual addresses,

0 commit comments

Comments
 (0)