@@ -260,6 +260,31 @@ LedDeviceWS2812b::LedDeviceWS2812b() :
260
260
printf (" WS2812b init finished \n " );
261
261
}
262
262
263
+ #ifdef WS2812_ASM_OPTI
264
+
265
+ // rotate register, used to move the 1 around :-)
266
+ static inline __attribute__ ((always_inline))
267
+ uint32_t arm_ror_imm(uint32_t v, uint32_t sh) {
268
+ uint32_t d;
269
+ asm (" ROR %[Rd], %[Rm], %[Is]" : [Rd] " =r" (d) : [Rm] " r" (v), [Is] " i" (sh));
270
+ return d;
271
+ }
272
+
273
+ static inline __attribute__ ((always_inline))
274
+ uint32_t arm_ror(uint32_t v, uint32_t sh) {
275
+ uint32_t d;
276
+ asm (" ROR %[Rd], %[Rm], %[Rs]" : [Rd] " =r" (d) : [Rm] " r" (v), [Rs] " r" (sh));
277
+ return d;
278
+ }
279
+
280
+
281
+ static inline __attribute__ ((always_inline))
282
+ uint32_t arm_Bit_Clear_imm(uint32_t v, uint32_t v2) {
283
+ uint32_t d;
284
+ asm (" BIC %[Rd], %[Rm], %[Rs]" : [Rd] " =r" (d) : [Rm] " r" (v), [Rs] " r" (v2));
285
+ return d;
286
+ }
287
+ #endif
263
288
264
289
int LedDeviceWS2812b::write (const std::vector<ColorRgb> &ledValues)
265
290
{
@@ -295,6 +320,9 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
295
320
// mLedCount = (NUM_DATA_WORDS - 1) / 2.25;
296
321
}
297
322
323
+ #ifdef WS2812_ASM_OPTI
324
+ unsigned int startbitPattern = 0x40000000 ; // = 0100 0000 0000 0000 0000 0000 0000 0000 pattern
325
+ #endif
298
326
299
327
300
328
for (size_t i=0 ; i<mLedCount ; i++) {
@@ -306,10 +334,26 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
306
334
307
335
// Iterate through color bits to get wire bits
308
336
for (int j=23 ; j>=0 ; j--) {
337
+ #ifdef WS2812_ASM_OPTI
338
+ // Fetch word the bit is in
339
+ unsigned int wordOffset = (int )(wireBit / 32 );
340
+ wireBit +=3 ;
341
+
342
+ // printBinary(startbitPattern, 32);
343
+ // printf(" %d\n", j);
344
+ if (colorBits & (1 << j)) {
345
+ PWMWaveform[wordOffset] |= startbitPattern;
346
+ } else {
347
+ PWMWaveform[wordOffset] = arm_Bit_Clear_imm (PWMWaveform[wordOffset], startbitPattern);
348
+ }
349
+
350
+ startbitPattern = arm_ror_imm (startbitPattern, 3 );
351
+
352
+ #else
309
353
unsigned char colorBit = (colorBits & (1 << j)) ? 1 : 0 ; // Holds current bit out of colorBits to be processed
310
-
311
354
setPWMBit (wireBit, colorBit);
312
355
wireBit +=3 ;
356
+ #endif
313
357
/* old code for better understanding
314
358
switch(colorBit) {
315
359
case 1:
@@ -328,6 +372,11 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
328
372
}
329
373
}
330
374
375
+ #ifdef WS2812_ASM_OPTI
376
+ // calculate the bits manually since it is not needed with asm
377
+ // wireBit += mLedCount * 24 *3;
378
+ // printf(" %d\n", wireBit);
379
+ #endif
331
380
// remove one to undo optimization
332
381
wireBit --;
333
382
@@ -344,6 +393,8 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
344
393
wireBit += 3 ;
345
394
}
346
395
396
+ // printBinary(PWMWaveform[(int)(oldwireBitValue / 32) -1 ], 32);
397
+ // printf(" post\n");
347
398
// printBinary(PWMWaveform[(int)(oldwireBitValue / 32)], 32);
348
399
// printf(" post\n");
349
400
0 commit comments