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

Commit c5e20fe

Browse files
committed
fixed strange bug with last led and pwm needs one more int
1 parent 4f27d34 commit c5e20fe

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

libsrc/leddevice/LedDeviceWS2812b.cpp

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ uint32_t arm_ror_imm(uint32_t v, uint32_t sh) {
270270
return d;
271271
}
272272

273+
// rotate register, used to move the 1 around, add 1 to int counter on carry
274+
static inline __attribute__((always_inline))
275+
uint32_t arm_ror_imm_add_on_carry(uint32_t v, uint32_t sh, uint32_t inc) {
276+
uint32_t d;
277+
asm ("RORS %[Rd], %[Rm], %[Is]\n\t"
278+
"ADDCS %[Rd1], %[Rd1], #1"
279+
: [Rd] "=r" (d), [Rd1] "+r" (inc): [Rm] "r" (v), [Is] "i" (sh));
280+
return d;
281+
}
282+
273283
static inline __attribute__((always_inline))
274284
uint32_t arm_ror(uint32_t v, uint32_t sh) {
275285
uint32_t d;
@@ -312,12 +322,12 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
312322
// 72 bits per pixel / 32 bits per word = 2.25 words per pixel
313323
// Add 1 to make sure the PWM FIFO gets the message: "we're sending zeroes"
314324
// Times 4 because DMA works in bytes, not words
315-
cbp->length = (mLedCount * 2.25) * 4;
316-
//cbp->length = ((mLedCount * 2.25) + 1) * 4;
325+
// cbp->length = (mLedCount * 2.25) * 4;
326+
cbp->length = ((mLedCount * 2.25) + 1) * 4;
317327
if(cbp->length > NUM_DATA_WORDS * 4) {
318328
cbp->length = NUM_DATA_WORDS * 4;
319-
mLedCount = NUM_DATA_WORDS / 2.25;
320-
//mLedCount = (NUM_DATA_WORDS - 1) / 2.25;
329+
// mLedCount = NUM_DATA_WORDS / 2.25;
330+
mLedCount = (NUM_DATA_WORDS - 1) / 2.25;
321331
}
322332

323333
#ifdef WS2812_ASM_OPTI
@@ -380,19 +390,39 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
380390
//remove one to undo optimization
381391
wireBit --;
382392

383-
// fill up the bytes
384-
int rest = 32 - wireBit % 32;
393+
// printBinary(PWMWaveform[(int)(wireBit / 32)], 32);
394+
// printf(" pre\n");
395+
396+
#ifdef WS2812_ASM_OPTI
397+
int rest = 32 - wireBit % 32; // 64: 32 - used Bits
398+
startbitPattern = (1 << (rest-1)); // set new bitpattern to start at the benigining of one bit (3 bit in wave form)
399+
rest += 32; // add one int extra for pwm
400+
401+
// printBinary(startbitPattern, 32);
402+
// printf(" startbit\n");
403+
385404
unsigned int oldwireBitValue = wireBit;
405+
unsigned int oldbitPattern = startbitPattern;
386406

387-
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
388-
// printf(" pre\n");
407+
// zero rest of the 4 bytes / int so that output is 0 (no data is send)
408+
for (int i = 0; i < rest; i += 3){
409+
unsigned int wordOffset = (int)(wireBit / 32);
410+
wireBit += 3;
411+
PWMWaveform[wordOffset] = arm_Bit_Clear_imm(PWMWaveform[wordOffset], startbitPattern);
412+
startbitPattern = arm_ror_imm(startbitPattern, 3);
413+
}
414+
415+
#else
416+
// fill up the bytes
417+
int rest = 32 - wireBit % 32 + 32; // 64: 32 - used Bits + 32 (one int extra for pwm)
418+
unsigned int oldwireBitValue = wireBit;
389419

390420
// zero rest of the 4 bytes / int so that output is 0 (no data is send)
391421
for (int i = 0; i < rest; i += 3){
392422
setPWMBit(wireBit, 0);
393423
wireBit += 3;
394424
}
395-
425+
#endif
396426
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32) -1 ], 32);
397427
// printf(" post\n");
398428
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
@@ -410,10 +440,21 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
410440

411441
// restore bit pattern
412442
wireBit = oldwireBitValue;
443+
444+
#ifdef WS2812_ASM_OPTI
445+
startbitPattern = oldbitPattern;
446+
for (int i = 0; i < rest; i += 3){
447+
unsigned int wordOffset = (int)(wireBit / 32);
448+
wireBit += 3;
449+
PWMWaveform[wordOffset] |= startbitPattern;
450+
startbitPattern = arm_ror_imm(startbitPattern, 3);
451+
}
452+
#else
413453
for (int i = 0; i < rest; i += 3){
414454
setPWMBit(wireBit, 1);
415455
wireBit += 3;
416456
}
457+
#endif
417458

418459
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
419460
// printf(" restored\n");

0 commit comments

Comments
 (0)