FastLED 3.6.0
Loading...
Searching...
No Matches
lib8tion.h
Go to the documentation of this file.
1#ifndef __INC_LIB8TION_H
2#define __INC_LIB8TION_H
3
4#include "FastLED.h"
5
6#ifndef __INC_LED_SYSDEFS_H
7#error WTH? led_sysdefs needs to be included first
8#endif
9
13
14
15FASTLED_NAMESPACE_BEGIN
16
17
18#include <stdint.h>
19
21#define LIB8STATIC __attribute__ ((unused)) static inline
23#define LIB8STATIC_ALWAYS_INLINE __attribute__ ((always_inline)) static inline
24
25#if !defined(__AVR__)
26#include <string.h>
27// for memmove, memcpy, and memset if not defined here
28#endif // end of !defined(__AVR__)
29
30#if defined(__arm__)
31
32#if defined(FASTLED_TEENSY3)
33// Can use Cortex M4 DSP instructions
34#define QADD8_C 0
35#define QADD7_C 0
36#define QADD8_ARM_DSP_ASM 1
37#define QADD7_ARM_DSP_ASM 1
38#else
39// Generic ARM
40#define QADD8_C 1
41#define QADD7_C 1
42#endif // end of defined(FASTLED_TEENSY3)
43
44#define QSUB8_C 1
45#define SCALE8_C 1
46#define SCALE16BY8_C 1
47#define SCALE16_C 1
48#define ABS8_C 1
49#define MUL8_C 1
50#define QMUL8_C 1
51#define ADD8_C 1
52#define SUB8_C 1
53#define EASE8_C 1
54#define AVG8_C 1
55#define AVG8R_C 1
56#define AVG7_C 1
57#define AVG16_C 1
58#define AVG16R_C 1
59#define AVG15_C 1
60#define BLEND8_C 1
61
62// end of #if defined(__arm__)
63
64#elif defined(ARDUINO_ARCH_APOLLO3)
65
66// Default to using the standard C functions for now
67#define QADD8_C 1
68#define QADD7_C 1
69#define QSUB8_C 1
70#define SCALE8_C 1
71#define SCALE16BY8_C 1
72#define SCALE16_C 1
73#define ABS8_C 1
74#define MUL8_C 1
75#define QMUL8_C 1
76#define ADD8_C 1
77#define SUB8_C 1
78#define EASE8_C 1
79#define AVG8_C 1
80#define AVG8R_C 1
81#define AVG7_C 1
82#define AVG16_C 1
83#define AVG16R_C 1
84#define AVG15_C 1
85#define BLEND8_C 1
86
87// end of #elif defined(ARDUINO_ARCH_APOLLO3)
88
89#elif defined(__AVR__)
90
91// AVR ATmega and friends Arduino
92
93#define QADD8_C 0
94#define QADD7_C 0
95#define QSUB8_C 0
96#define ABS8_C 0
97#define ADD8_C 0
98#define SUB8_C 0
99#define AVG8_C 0
100#define AVG8R_C 0
101#define AVG7_C 0
102#define AVG16_C 0
103#define AVG16R_C 0
104#define AVG15_C 0
105
106#define QADD8_AVRASM 1
107#define QADD7_AVRASM 1
108#define QSUB8_AVRASM 1
109#define ABS8_AVRASM 1
110#define ADD8_AVRASM 1
111#define SUB8_AVRASM 1
112#define AVG8_AVRASM 1
113#define AVG8R_AVRASM 1
114#define AVG7_AVRASM 1
115#define AVG16_AVRASM 1
116#define AVG16R_AVRASM 1
117#define AVG15_AVRASM 1
118
119// Note: these require hardware MUL instruction
120// -- sorry, ATtiny!
121#if !defined(LIB8_ATTINY)
122#define SCALE8_C 0
123#define SCALE16BY8_C 0
124#define SCALE16_C 0
125#define MUL8_C 0
126#define QMUL8_C 0
127#define EASE8_C 0
128#define BLEND8_C 0
129#define SCALE8_AVRASM 1
130#define SCALE16BY8_AVRASM 1
131#define SCALE16_AVRASM 1
132#define MUL8_AVRASM 1
133#define QMUL8_AVRASM 1
134#define EASE8_AVRASM 1
135#define CLEANUP_R1_AVRASM 1
136#define BLEND8_AVRASM 1
137#else
138// On ATtiny, we just use C implementations
139#define SCALE8_C 1
140#define SCALE16BY8_C 1
141#define SCALE16_C 1
142#define MUL8_C 1
143#define QMUL8_C 1
144#define EASE8_C 1
145#define BLEND8_C 1
146#define SCALE8_AVRASM 0
147#define SCALE16BY8_AVRASM 0
148#define SCALE16_AVRASM 0
149#define MUL8_AVRASM 0
150#define QMUL8_AVRASM 0
151#define EASE8_AVRASM 0
152#define BLEND8_AVRASM 0
153#endif // end of !defined(LIB8_ATTINY)
154
155// end of #elif defined(__AVR__)
156
157#else
158
159// Doxygen: ignore these macros
161
162// unspecified architecture, so
163// no ASM, everything in C
164#define QADD8_C 1
165#define QADD7_C 1
166#define QSUB8_C 1
167#define SCALE8_C 1
168#define SCALE16BY8_C 1
169#define SCALE16_C 1
170#define ABS8_C 1
171#define MUL8_C 1
172#define QMUL8_C 1
173#define ADD8_C 1
174#define SUB8_C 1
175#define EASE8_C 1
176#define AVG8_C 1
177#define AVG8R_C 1
178#define AVG7_C 1
179#define AVG16_C 1
180#define AVG16R_C 1
181#define AVG15_C 1
182#define BLEND8_C 1
183
185
186#endif
187
378
379
398
402typedef uint8_t fract8;
403
407typedef int8_t sfract7;
408
412typedef uint16_t fract16;
413
417typedef int16_t sfract15;
418
419
420typedef uint16_t accum88;
421typedef int16_t saccum78;
422typedef uint32_t accum1616;
423typedef int32_t saccum1516;
424typedef uint16_t accum124;
425typedef int32_t saccum114;
426
427
430typedef union {
431 uint32_t i;
432 float f;
433 struct {
434 uint32_t mantissa: 23;
435 uint32_t exponent: 8;
436 uint32_t signbit: 1;
437 };
438 struct {
439 uint32_t mant7 : 7;
440 uint32_t mant16: 16;
441 uint32_t exp_ : 8;
442 uint32_t sb_ : 1;
443 };
444 struct {
445 uint32_t mant_lo8 : 8;
446 uint32_t mant_hi16_exp_lo1 : 16;
447 uint32_t sb_exphi7 : 8;
448 };
450
452
453
454#include "lib8tion/math8.h"
455#include "lib8tion/scale8.h"
456#include "lib8tion/random8.h"
457#include "lib8tion/trig8.h"
458
460
461
462
463
464
465
466
473
476{
477 return y / 32768.0;
478}
479
484{
485 return f * 32768.0;
486}
487
489
490
491
498
499#if defined(__AVR__) || defined(FASTLED_DOXYGEN)
500extern "C" {
501void * memmove8( void * dst, const void * src, uint16_t num );
502void * memcpy8 ( void * dst, const void * src, uint16_t num ) __attribute__ ((noinline));
503void * memset8 ( void * ptr, uint8_t value, uint16_t num ) __attribute__ ((noinline)) ;
504}
505#else
506// on non-AVR platforms, these names just call standard libc.
507#define memmove8 memmove
508#define memcpy8 memcpy
509#define memset8 memset
510#endif
511
513
514
529
532LIB8STATIC uint8_t lerp8by8( uint8_t a, uint8_t b, fract8 frac)
533{
534 uint8_t result;
535 if( b > a) {
536 uint8_t delta = b - a;
537 uint8_t scaled = scale8( delta, frac);
538 result = a + scaled;
539 } else {
540 uint8_t delta = a - b;
541 uint8_t scaled = scale8( delta, frac);
542 result = a - scaled;
543 }
544 return result;
545}
546
549LIB8STATIC uint16_t lerp16by16( uint16_t a, uint16_t b, fract16 frac)
550{
551 uint16_t result;
552 if( b > a ) {
553 uint16_t delta = b - a;
554 uint16_t scaled = scale16(delta, frac);
555 result = a + scaled;
556 } else {
557 uint16_t delta = a - b;
558 uint16_t scaled = scale16( delta, frac);
559 result = a - scaled;
560 }
561 return result;
562}
563
566LIB8STATIC uint16_t lerp16by8( uint16_t a, uint16_t b, fract8 frac)
567{
568 uint16_t result;
569 if( b > a) {
570 uint16_t delta = b - a;
571 uint16_t scaled = scale16by8( delta, frac);
572 result = a + scaled;
573 } else {
574 uint16_t delta = a - b;
575 uint16_t scaled = scale16by8( delta, frac);
576 result = a - scaled;
577 }
578 return result;
579}
580
583LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac)
584{
585 int16_t result;
586 if( b > a) {
587 uint16_t delta = b - a;
588 uint16_t scaled = scale16by8( delta, frac);
589 result = a + scaled;
590 } else {
591 uint16_t delta = a - b;
592 uint16_t scaled = scale16by8( delta, frac);
593 result = a - scaled;
594 }
595 return result;
596}
597
600LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac)
601{
602 int16_t result;
603 if( b > a) {
604 uint16_t delta = b - a;
605 uint16_t scaled = scale16( delta, frac);
606 result = a + scaled;
607 } else {
608 uint16_t delta = a - b;
609 uint16_t scaled = scale16( delta, frac);
610 result = a - scaled;
611 }
612 return result;
613}
614
636LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
637{
638 uint8_t rangeWidth = rangeEnd - rangeStart;
639 uint8_t out = scale8( in, rangeWidth);
640 out += rangeStart;
641 return out;
642}
643
645
646
653
656#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
657LIB8STATIC uint8_t ease8InOutQuad( uint8_t i)
658{
659 uint8_t j = i;
660 if( j & 0x80 ) {
661 j = 255 - j;
662 }
663 uint8_t jj = scale8( j, j);
664 uint8_t jj2 = jj << 1;
665 if( i & 0x80 ) {
666 jj2 = 255 - jj2;
667 }
668 return jj2;
669}
670
671#elif EASE8_AVRASM == 1
672// This AVR asm version of ease8InOutQuad preserves one more
673// low-bit of precision than the C version, and is also slightly
674// smaller and faster.
675LIB8STATIC uint8_t ease8InOutQuad(uint8_t val) {
676 uint8_t j=val;
677 asm volatile (
678 "sbrc %[val], 7 \n"
679 "com %[j] \n"
680 "mul %[j], %[j] \n"
681 "add r0, %[j] \n"
682 "ldi %[j], 0 \n"
683 "adc %[j], r1 \n"
684 "lsl r0 \n" // carry = high bit of low byte of mul product
685 "rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision
686 "sbrc %[val], 7 \n"
687 "com %[j] \n"
688 "clr __zero_reg__ \n"
689 : [j] "+&a" (j)
690 : [val] "a" (val)
691 : "r0", "r1"
692 );
693 return j;
694}
695
696#else
697#error "No implementation for ease8InOutQuad available."
698#endif
699
702LIB8STATIC uint16_t ease16InOutQuad( uint16_t i)
703{
704 uint16_t j = i;
705 if( j & 0x8000 ) {
706 j = 65535 - j;
707 }
708 uint16_t jj = scale16( j, j);
709 uint16_t jj2 = jj << 1;
710 if( i & 0x8000 ) {
711 jj2 = 65535 - jj2;
712 }
713 return jj2;
714}
715
716
720{
721 uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i);
722 uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i);
723
724 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
725
726 /* the code generated for the above *'s automatically
727 cleans up R1, so there's no need to explicitily call
728 cleanup_R1(); */
729
730 uint8_t result = r1;
731
732 // if we got "256", return 255:
733 if( r1 & 0x100 ) {
734 result = 255;
735 }
736 return result;
737}
738
739
747#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
749{
750 if( i < 64) {
751 // start with slope 0.5
752 i /= 2;
753 } else if( i > (255 - 64)) {
754 // end with slope 0.5
755 i = 255 - i;
756 i /= 2;
757 i = 255 - i;
758 } else {
759 // in the middle, use slope 192/128 = 1.5
760 i -= 64;
761 i += (i / 2);
762 i += 32;
763 }
764
765 return i;
766}
767
768#elif EASE8_AVRASM == 1
770{
771 // takes around 7 cycles on AVR
772 asm volatile (
773 " subi %[i], 64 \n\t"
774 " cpi %[i], 128 \n\t"
775 " brcc Lshift_%= \n\t"
776
777 // middle case
778 " mov __tmp_reg__, %[i] \n\t"
779 " lsr __tmp_reg__ \n\t"
780 " add %[i], __tmp_reg__ \n\t"
781 " subi %[i], 224 \n\t"
782 " rjmp Ldone_%= \n\t"
783
784 // start or end case
785 "Lshift_%=: \n\t"
786 " lsr %[i] \n\t"
787 " subi %[i], 96 \n\t"
788
789 "Ldone_%=: \n\t"
790
791 : [i] "+a" (i)
792 :
793 : "r0"
794 );
795 return i;
796}
797#else
798#error "No implementation for ease8 available."
799#endif
800
802
803
810
811
823LIB8STATIC uint8_t triwave8(uint8_t in)
824{
825 if( in & 0x80) {
826 in = 255 - in;
827 }
828 uint8_t out = in << 1;
829 return out;
830}
831
842LIB8STATIC uint8_t quadwave8(uint8_t in)
843{
844 return ease8InOutQuad( triwave8( in));
845}
846
850LIB8STATIC uint8_t cubicwave8(uint8_t in)
851{
852 return ease8InOutCubic( triwave8( in));
853}
854
855
879LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth=128)
880{
881 if( in < pulsewidth || (pulsewidth == 255)) {
882 return 255;
883 } else {
884 return 0;
885 }
886}
887
889
890
891
894
899template<class T, int F, int I> class q {
900 T i:I;
901 T f:F;
902public:
904 q(float fx) { i = fx; f = (fx-i) * (1<<F); }
906 q(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
907
909 uint32_t operator*(uint32_t v) { return (v*i) + ((v*f)>>F); }
911 uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); }
913 int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); }
915 int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); }
916#if defined(FASTLED_ARM) | defined(FASTLED_RISCV) | defined(FASTLED_APOLLO3)
918 int operator*(int v) { return (v*i) + ((v*f)>>F); }
919#endif
920};
921
922template<class T, int F, int I> static uint32_t operator*(uint32_t v, q<T,F,I> & q) { return q * v; }
923template<class T, int F, int I> static uint16_t operator*(uint16_t v, q<T,F,I> & q) { return q * v; }
924template<class T, int F, int I> static int32_t operator*(int32_t v, q<T,F,I> & q) { return q * v; }
925template<class T, int F, int I> static int16_t operator*(int16_t v, q<T,F,I> & q) { return q * v; }
926#if defined(FASTLED_ARM) | defined(FASTLED_RISCV) | defined(FASTLED_APOLLO3)
927template<class T, int F, int I> static int operator*(int v, q<T,F,I> & q) { return q * v; }
928#endif
929
938
940
942
943
950
951#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
952// Forward declaration of Arduino function 'millis'.
953//uint32_t millis();
954
965#define GET_MILLIS millis
966#else
967uint32_t get_millisecond_timer();
968#define GET_MILLIS get_millisecond_timer
969#endif
970
972
973
976
977
1016
1017
1025LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase = 0)
1026{
1027 // BPM is 'beats per minute', or 'beats per 60000ms'.
1028 // To avoid using the (slower) division operator, we
1029 // want to convert 'beats per 60000ms' to 'beats per 65536ms',
1030 // and then use a simple, fast bit-shift to divide by 65536.
1031 //
1032 // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256.
1033 // The conversion is accurate to about 0.05%, more or less,
1034 // e.g. if you ask for "120 BPM", you'll get about "119.93".
1035 return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
1036}
1037
1041LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase = 0)
1042{
1043 // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed
1044 if( beats_per_minute < 256) beats_per_minute <<= 8;
1045 return beat88(beats_per_minute, timebase);
1046}
1047
1051LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase = 0)
1052{
1053 return beat16( beats_per_minute, timebase) >> 8;
1054}
1055
1056
1067LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
1068 uint32_t timebase = 0, uint16_t phase_offset = 0)
1069{
1070 uint16_t beat = beat88( beats_per_minute_88, timebase);
1071 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
1072 uint16_t rangewidth = highest - lowest;
1073 uint16_t scaledbeat = scale16( beatsin, rangewidth);
1074 uint16_t result = lowest + scaledbeat;
1075 return result;
1076}
1077
1085LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
1086 uint32_t timebase = 0, uint16_t phase_offset = 0)
1087{
1088 uint16_t beat = beat16( beats_per_minute, timebase);
1089 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
1090 uint16_t rangewidth = highest - lowest;
1091 uint16_t scaledbeat = scale16( beatsin, rangewidth);
1092 uint16_t result = lowest + scaledbeat;
1093 return result;
1094}
1095
1103LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
1104 uint32_t timebase = 0, uint8_t phase_offset = 0)
1105{
1106 uint8_t beat = beat8( beats_per_minute, timebase);
1107 uint8_t beatsin = sin8( beat + phase_offset);
1108 uint8_t rangewidth = highest - lowest;
1109 uint8_t scaledbeat = scale8( beatsin, rangewidth);
1110 uint8_t result = lowest + scaledbeat;
1111 return result;
1112}
1113
1115
1117
1118
1123
1127{
1128 uint32_t ms = GET_MILLIS();
1129 uint16_t s16;
1130 s16 = ms / 1000;
1131 return s16;
1132}
1133
1137{
1138 uint32_t ms = GET_MILLIS();
1139 uint16_t m16;
1140 m16 = (ms / (60000L)) & 0xFFFF;
1141 return m16;
1142}
1143
1147{
1148 uint32_t ms = GET_MILLIS();
1149 uint8_t h8;
1150 h8 = (ms / (3600000L)) & 0xFF;
1151 return h8;
1152}
1153
1154
1168LIB8STATIC uint16_t div1024_32_16( uint32_t in32)
1169{
1170 uint16_t out16;
1171#if defined(__AVR__)
1172 asm volatile (
1173 " lsr %D[in] \n\t"
1174 " ror %C[in] \n\t"
1175 " ror %B[in] \n\t"
1176 " lsr %D[in] \n\t"
1177 " ror %C[in] \n\t"
1178 " ror %B[in] \n\t"
1179 " mov %B[out],%C[in] \n\t"
1180 " mov %A[out],%B[in] \n\t"
1181 : [in] "+r" (in32),
1182 [out] "=r" (out16)
1183 );
1184#else
1185 out16 = (in32 >> 10) & 0xFFFF;
1186#endif
1187 return out16;
1188}
1189
1194{
1195 uint32_t ms = GET_MILLIS();
1196 uint16_t s16;
1197 s16 = div1024_32_16( ms);
1198 return s16;
1199}
1200
1204#if 1
1205#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1206class NAME { \
1207public: \
1208 TIMETYPE mPrevTrigger; \
1209 TIMETYPE mPeriod; \
1210 \
1211 NAME() { reset(); mPeriod = 1; }; \
1212 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
1213 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
1214 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
1215 TIMETYPE getPeriod() { return mPeriod; }; \
1216 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
1217 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
1218 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
1219 bool ready() { \
1220 bool isReady = (getElapsed() >= mPeriod); \
1221 if( isReady ) { reset(); } \
1222 return isReady; \
1223 } \
1224 void reset() { mPrevTrigger = getTime(); }; \
1225 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1226 \
1227 operator bool() { return ready(); } \
1228};
1229
1234
1235#if defined(FASTLED_DOXYGEN)
1249public:
1250 TIMETYPE mPrevTrigger;
1251 TIMETYPE mPeriod;
1252
1257 CEveryNTime(TIMETYPE period) { reset(); setPeriod(period); };
1258
1260 void setPeriod( TIMETYPE period) { mPeriod = period; };
1261
1263 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); };
1264
1266 TIMETYPE getPeriod() { return mPeriod; };
1267
1269 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; }
1270
1272 TIMETYPE getRemaining() { return mPeriod - getElapsed(); }
1273
1275 TIMETYPE getLastTriggerTime() { return mPrevTrigger; }
1276
1278 bool ready() {
1279 bool isReady = (getElapsed() >= mPeriod);
1280 if( isReady ) { reset(); }
1281 return isReady;
1282 }
1283
1285 void reset() { mPrevTrigger = getTime(); };
1286
1289
1291 operator bool() { return ready(); }
1292};
1293#endif // FASTLED_DOXYGEN
1294
1297
1300
1303
1306
1309
1311#define CEveryNMilliseconds CEveryNMillis
1313
1314#else
1315
1316// Under C++11 rules, we would be allowed to use not-external
1317// -linkage-type symbols as template arguments,
1318// e.g., LIB8STATIC seconds16, and we'd be able to use these
1319// templates as shown below.
1320// However, under C++03 rules, we cannot do that, and thus we
1321// have to resort to the preprocessor to 'instantiate' 'templates',
1322// as handled above.
1323template<typename timeType,timeType (*timeGetter)()>
1324class CEveryNTimePeriods {
1325public:
1326 timeType mPrevTrigger;
1327 timeType mPeriod;
1328
1329 CEveryNTimePeriods() { reset(); mPeriod = 1; };
1330 CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
1331 void setPeriod( timeType period) { mPeriod = period; };
1332 timeType getTime() { return (timeType)(timeGetter()); };
1333 timeType getPeriod() { return mPeriod; };
1334 timeType getElapsed() { return getTime() - mPrevTrigger; }
1335 timeType getRemaining() { return mPeriod - getElapsed(); }
1336 timeType getLastTriggerTime() { return mPrevTrigger; }
1337 bool ready() {
1338 bool isReady = (getElapsed() >= mPeriod);
1339 if( isReady ) { reset(); }
1340 return isReady;
1341 }
1342 void reset() { mPrevTrigger = getTime(); };
1343 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1344
1345 operator bool() { return ready(); }
1346};
1347typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;
1348typedef CEveryNTimePeriods<uint16_t,bseconds16> CEveryNBSeconds;
1349typedef CEveryNTimePeriods<uint32_t,millis> CEveryNMillis;
1350typedef CEveryNTimePeriods<uint16_t,minutes16> CEveryNMinutes;
1351typedef CEveryNTimePeriods<uint8_t,hours8> CEveryNHours;
1352#endif
1353
1354
1369
1371#define CONCAT_HELPER( x, y ) x##y
1372#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1374
1375
1378#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1379
1382#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1383
1384
1387#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1388
1391#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1392
1393
1396#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1397
1400#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1401
1402
1405#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1406
1409#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1410
1411
1414#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1415
1418#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1419
1420
1422#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1424#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1425
1428
1429
1430// These defines are used to declare hidden or commented symbols for the
1431// purposes of Doxygen documentation generation. They do not affect your program.
1432#ifdef FASTLED_DOXYGEN
1436#define USE_GET_MILLISECOND_TIMER
1437#endif
1438
1439FASTLED_NAMESPACE_END
1440
1441#endif
central include file for FastLED, defines the CFastLED class/object
Time interval checking class.
Definition lib8tion.h:1248
void trigger()
Reset the timestamp so it is ready() on next call.
Definition lib8tion.h:1288
TIMETYPE mPeriod
Timing interval to check.
Definition lib8tion.h:1251
CEveryNTime(TIMETYPE period)
Constructor.
Definition lib8tion.h:1257
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
Definition lib8tion.h:1275
CEveryNTime()
Default constructor.
Definition lib8tion.h:1254
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
Definition lib8tion.h:1263
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
Definition lib8tion.h:1269
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
Definition lib8tion.h:1260
bool ready()
Check if the time interval has elapsed.
Definition lib8tion.h:1278
void reset()
Reset the timestamp to the current time.
Definition lib8tion.h:1285
TIMETYPE getPeriod()
Get the time interval between triggers.
Definition lib8tion.h:1266
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
Definition lib8tion.h:1250
TIMETYPE getRemaining()
Get the time until the next trigger event.
Definition lib8tion.h:1272
Template class for representing fractional ints.
Definition lib8tion.h:899
int16_t operator*(int16_t v)
Multiply the fractional int by a value.
Definition lib8tion.h:915
uint32_t operator*(uint32_t v)
Multiply the fractional int by a value.
Definition lib8tion.h:909
q(float fx)
Constructor, storing a float as a fractional int.
Definition lib8tion.h:904
uint16_t operator*(uint16_t v)
Multiply the fractional int by a value.
Definition lib8tion.h:911
int32_t operator*(int32_t v)
Multiply the fractional int by a value.
Definition lib8tion.h:913
q(uint8_t _i, uint8_t _f)
Constructor, storing a fractional int directly.
Definition lib8tion.h:906
LIB8STATIC uint8_t beat8(accum88 beats_per_minute, uint32_t timebase=0)
Generates an 8-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:1051
LIB8STATIC uint16_t beat88(accum88 beats_per_minute_88, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM, with BPM specified in Q8.8 fixed-point format.
Definition lib8tion.h:1025
LIB8STATIC uint16_t beatsin16(accum88 beats_per_minute, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:1085
LIB8STATIC uint16_t beat16(accum88 beats_per_minute, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:1041
LIB8STATIC uint8_t beatsin8(accum88 beats_per_minute, uint8_t lowest=0, uint8_t highest=255, uint32_t timebase=0, uint8_t phase_offset=0)
Generates an 8-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:1103
LIB8STATIC uint16_t beatsin88(accum88 beats_per_minute_88, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:1067
LIB8STATIC uint16_t ease16InOutQuad(uint16_t i)
16-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:702
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
Definition lib8tion.h:748
LIB8STATIC uint8_t ease8InOutQuad(uint8_t i)
8-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:657
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
Definition lib8tion.h:719
void * memcpy8(void *dst, const void *src, uint16_t num)
Faster alternative to memcpy() on AVR.
void * memset8(void *ptr, uint8_t value, uint16_t num)
Faster alternative to memset() on AVR.
void * memmove8(void *dst, const void *src, uint16_t num)
Faster alternative to memmove() on AVR.
LIB8STATIC sfract15 floatToSfract15(float f)
Conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point (sfract15).
Definition lib8tion.h:483
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
Definition lib8tion.h:475
int16_t sfract15
ANSI: signed _Fract.
Definition lib8tion.h:417
q< uint16_t, 12, 4 > q124
A 12.4 integer (12 bits integer, 4 bits fraction)
Definition lib8tion.h:937
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition lib8tion.h:420
uint8_t fract8
ANSI: unsigned short _Fract.
Definition lib8tion.h:402
uint16_t accum124
no direct ANSI counterpart. 12 bits int, 4 bits fraction
Definition lib8tion.h:424
int8_t sfract7
ANSI: signed short _Fract.
Definition lib8tion.h:407
q< uint8_t, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
Definition lib8tion.h:931
int16_t saccum78
ANSI: signed short _Accum. 7 bits int, 8 bits fraction.
Definition lib8tion.h:421
int32_t saccum114
no direct ANSI counterpart. 1 bit int, 14 bits fraction
Definition lib8tion.h:425
uint16_t fract16
ANSI: unsigned _Fract.
Definition lib8tion.h:412
int32_t saccum1516
ANSI: signed _Accum. 15 bits int, 16 bits fraction.
Definition lib8tion.h:423
q< uint16_t, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits fraction)
Definition lib8tion.h:935
uint32_t accum1616
ANSI: signed _Accum. 16 bits int, 16 bits fraction.
Definition lib8tion.h:422
q< uint8_t, 6, 2 > q62
A 6.2 integer (6 bits integer, 2 bits fraction)
Definition lib8tion.h:933
LIB8STATIC uint8_t lerp8by8(uint8_t a, uint8_t b, fract8 frac)
Linear interpolation between two unsigned 8-bit values, with 8-bit fraction.
Definition lib8tion.h:532
LIB8STATIC uint16_t lerp16by16(uint16_t a, uint16_t b, fract16 frac)
Linear interpolation between two unsigned 16-bit values, with 16-bit fraction.
Definition lib8tion.h:549
LIB8STATIC uint16_t lerp16by8(uint16_t a, uint16_t b, fract8 frac)
Linear interpolation between two unsigned 16-bit values, with 8-bit fraction.
Definition lib8tion.h:566
LIB8STATIC int16_t lerp15by8(int16_t a, int16_t b, fract8 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:583
LIB8STATIC int16_t lerp15by16(int16_t a, int16_t b, fract16 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:600
LIB8STATIC uint8_t map8(uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
Map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
Definition lib8tion.h:636
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8() does not clean up the R1 register on AVR.
Definition scale8.h:169
LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale)
Scale a 16-bit unsigned value by an 16-bit value, which is treated as the numerator of a fraction who...
Definition scale8.h:543
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8(uint16_t i, fract8 scale)
Scale a 16-bit unsigned value by an 8-bit value, which is treated as the numerator of a fraction whos...
Definition scale8.h:472
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:30
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
Definition lib8tion.h:1205
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
Definition lib8tion.h:1136
LIB8STATIC uint16_t bseconds16()
Returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a second lon...
Definition lib8tion.h:1193
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:965
LIB8STATIC uint16_t div1024_32_16(uint32_t in32)
Helper routine to divide a 32-bit value by 1024, returning only the low 16 bits.
Definition lib8tion.h:1168
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
Definition lib8tion.h:1146
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
Definition lib8tion.h:1126
#define sin16
Platform-independent alias of the fast sin implementation.
Definition trig8.h:90
#define sin8
Platform-independent alias of the fast sin implementation.
Definition trig8.h:211
LIB8STATIC uint8_t cubicwave8(uint8_t in)
Cubic waveform generator.
Definition lib8tion.h:850
LIB8STATIC uint8_t squarewave8(uint8_t in, uint8_t pulsewidth=128)
Square wave generator.
Definition lib8tion.h:879
LIB8STATIC uint8_t quadwave8(uint8_t in)
Quadratic waveform generator.
Definition lib8tion.h:842
LIB8STATIC uint8_t triwave8(uint8_t in)
Triangle wave generator.
Definition lib8tion.h:823
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8tion.h:21
Fast, efficient 8-bit math functions specifically designed for high-performance LED programming.
Fast, efficient random number generators specifically designed for high-performance LED programming.
Fast, efficient 8-bit scaling functions specifically designed for high-performance LED programming.
Fast, efficient 8-bit trigonometry functions specifically designed for high-performance LED programmi...
typedef for IEEE754 "binary32" float type internals
Definition lib8tion.h:430
uint32_t mantissa
23-bit mantissa
Definition lib8tion.h:434
uint32_t signbit
sign bit
Definition lib8tion.h:436
uint32_t mant_lo8
Definition lib8tion.h:445
uint32_t mant16
Definition lib8tion.h:440
uint32_t mant_hi16_exp_lo1
Definition lib8tion.h:446
uint32_t i
raw value, as an integer
Definition lib8tion.h:431
float f
raw value, as a float
Definition lib8tion.h:432
uint32_t exponent
8-bit exponent
Definition lib8tion.h:435
uint32_t sb_exphi7
Definition lib8tion.h:447