@@ -270,6 +270,16 @@ uint32_t arm_ror_imm(uint32_t v, uint32_t sh) {
270
270
return d;
271
271
}
272
272
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
+
273
283
static inline __attribute__ ((always_inline))
274
284
uint32_t arm_ror(uint32_t v, uint32_t sh) {
275
285
uint32_t d;
@@ -312,12 +322,12 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
312
322
// 72 bits per pixel / 32 bits per word = 2.25 words per pixel
313
323
// Add 1 to make sure the PWM FIFO gets the message: "we're sending zeroes"
314
324
// 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 ;
317
327
if (cbp->length > NUM_DATA_WORDS * 4 ) {
318
328
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 ;
321
331
}
322
332
323
333
#ifdef WS2812_ASM_OPTI
@@ -380,19 +390,39 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
380
390
// remove one to undo optimization
381
391
wireBit --;
382
392
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
+
385
404
unsigned int oldwireBitValue = wireBit;
405
+ unsigned int oldbitPattern = startbitPattern;
386
406
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;
389
419
390
420
// zero rest of the 4 bytes / int so that output is 0 (no data is send)
391
421
for (int i = 0 ; i < rest; i += 3 ){
392
422
setPWMBit (wireBit, 0 );
393
423
wireBit += 3 ;
394
424
}
395
-
425
+ # endif
396
426
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32) -1 ], 32);
397
427
// printf(" post\n");
398
428
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
@@ -410,10 +440,21 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
410
440
411
441
// restore bit pattern
412
442
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
413
453
for (int i = 0 ; i < rest; i += 3 ){
414
454
setPWMBit (wireBit, 1 );
415
455
wireBit += 3 ;
416
456
}
457
+ #endif
417
458
418
459
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
419
460
// printf(" restored\n");
0 commit comments