Scale a 16-bit unsigned value by an 16-bit value, which is treated as the numerator of a fraction whose denominator is 65536.
551 {
552#if SCALE16_C == 1
553 uint16_t result;
554#if FASTLED_SCALE8_FIXED == 1
555 result = ((uint32_t)(i) * (1 + (uint32_t)(
scale))) / 65536;
556#else
557 result = ((uint32_t)(i) * (uint32_t)(
scale)) / 65536;
558#endif
559 return result;
560#elif SCALE16_AVRASM == 1
561#if FASTLED_SCALE8_FIXED == 1
562
563
564
565
566
567
568
569 uint32_t result;
570 asm volatile(
571
572 " mul %A[i], %A[scale] \n\t"
573
574
575
576
577
578 " movw %A[result], r0 \n\t"
579
580
581
582
583
584 : [result] "=r"(result)
586 : "r0", "r1");
587
588 asm volatile(
589
590 " mul %B[i], %B[scale] \n\t"
591
592
593 " movw %C[result], r0 \n\t"
594 : [result] "+r"(result)
596 : "r0", "r1");
597
598 const uint8_t zero = 0;
599 asm volatile(
600
601 " mul %B[i], %A[scale] \n\t"
602
603 " add %B[result], r0 \n\t"
604 " adc %C[result], r1 \n\t"
605 " adc %D[result], %[zero] \n\t"
606
607
608 " mul %A[i], %B[scale] \n\t"
609
610 " add %B[result], r0 \n\t"
611 " adc %C[result], r1 \n\t"
612 " adc %D[result], %[zero] \n\t"
613
614
615 " clr r1 \n\t"
616
617 : [result] "+r"(result)
618 : [i]
"r"(i), [
scale]
"r"(
scale), [zero]
"r"(zero)
619 : "r0", "r1");
620
621 asm volatile(
622
623 " add %A[result], %A[i] \n\t"
624 " adc %B[result], %B[i] \n\t"
625 " adc %C[result], %[zero] \n\t"
626 " adc %D[result], %[zero] \n\t"
627 : [result] "+r"(result)
628 : [i] "r"(i), [zero] "r"(zero));
629
630 result = result >> 16;
631 return result;
632#else
633 uint32_t result;
634 asm volatile(
635
636 " mul %A[i], %A[scale] \n\t"
637
638
639
640
641
642 " movw %A[result], r0 \n\t"
643
644
645
646
647
648
649
650 : [result] "=r"(result)
652 : "r0", "r1");
653
654 asm volatile(
655
656 " mul %B[i], %B[scale] \n\t"
657
658
659 " movw %C[result], r0 \n\t"
660 : [result] "+r"(result)
662 : "r0", "r1");
663
664 const uint8_t zero = 0;
665 asm volatile(
666
667 " mul %B[i], %A[scale] \n\t"
668
669 " add %B[result], r0 \n\t"
670 " adc %C[result], r1 \n\t"
671 " adc %D[result], %[zero] \n\t"
672
673
674 " mul %A[i], %B[scale] \n\t"
675
676 " add %B[result], r0 \n\t"
677 " adc %C[result], r1 \n\t"
678 " adc %D[result], %[zero] \n\t"
679
680
681 " clr r1 \n\t"
682
683 : [result] "+r"(result)
684 : [i]
"r"(i), [
scale]
"r"(
scale), [zero]
"r"(zero)
685 : "r0", "r1");
686
687 result = result >> 16;
688 return result;
689#endif
690#else
691#error "No implementation for scale16 available."
692#endif
693}