FastLED 3.9.3
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#include "lib8tion/types.h"
6
7#ifndef __INC_LED_SYSDEFS_H
8#error WTH? led_sysdefs needs to be included first
9#endif
10
14
15#include <stdint.h>
16#include "lib8tion/lib8static.h"
17#include "qfx.h"
18
19
20#if !defined(__AVR__)
21#include <string.h>
22// for memmove, memcpy, and memset if not defined here
23#endif // end of !defined(__AVR__)
24
25#if defined(__arm__)
26
27#if defined(FASTLED_TEENSY3)
28// Can use Cortex M4 DSP instructions
29#define QADD8_C 0
30#define QADD7_C 0
31#define QADD8_ARM_DSP_ASM 1
32#define QADD7_ARM_DSP_ASM 1
33#else
34// Generic ARM
35#define QADD8_C 1
36#define QADD7_C 1
37#endif // end of defined(FASTLED_TEENSY3)
38
39#define QSUB8_C 1
40#define SCALE8_C 1
41#define SCALE16BY8_C 1
42#define SCALE16_C 1
43#define ABS8_C 1
44#define MUL8_C 1
45#define QMUL8_C 1
46#define ADD8_C 1
47#define SUB8_C 1
48#define EASE8_C 1
49#define AVG8_C 1
50#define AVG8R_C 1
51#define AVG7_C 1
52#define AVG16_C 1
53#define AVG16R_C 1
54#define AVG15_C 1
55#define BLEND8_C 1
56
57// end of #if defined(__arm__)
58
59#elif defined(ARDUINO_ARCH_APOLLO3)
60
61// Default to using the standard C functions for now
62#define QADD8_C 1
63#define QADD7_C 1
64#define QSUB8_C 1
65#define SCALE8_C 1
66#define SCALE16BY8_C 1
67#define SCALE16_C 1
68#define ABS8_C 1
69#define MUL8_C 1
70#define QMUL8_C 1
71#define ADD8_C 1
72#define SUB8_C 1
73#define EASE8_C 1
74#define AVG8_C 1
75#define AVG8R_C 1
76#define AVG7_C 1
77#define AVG16_C 1
78#define AVG16R_C 1
79#define AVG15_C 1
80#define BLEND8_C 1
81
82// end of #elif defined(ARDUINO_ARCH_APOLLO3)
83
84#elif defined(__AVR__)
85
86// AVR ATmega and friends Arduino
87
88#define QADD8_C 0
89#define QADD7_C 0
90#define QSUB8_C 0
91#define ABS8_C 0
92#define ADD8_C 0
93#define SUB8_C 0
94#define AVG8_C 0
95#define AVG8R_C 0
96#define AVG7_C 0
97#define AVG16_C 0
98#define AVG16R_C 0
99#define AVG15_C 0
100
101#define QADD8_AVRASM 1
102#define QADD7_AVRASM 1
103#define QSUB8_AVRASM 1
104#define ABS8_AVRASM 1
105#define ADD8_AVRASM 1
106#define SUB8_AVRASM 1
107#define AVG8_AVRASM 1
108#define AVG8R_AVRASM 1
109#define AVG7_AVRASM 1
110#define AVG16_AVRASM 1
111#define AVG16R_AVRASM 1
112#define AVG15_AVRASM 1
113
114// Note: these require hardware MUL instruction
115// -- sorry, ATtiny!
116#if !defined(LIB8_ATTINY)
117#define SCALE8_C 0
118#define SCALE16BY8_C 0
119#define SCALE16_C 0
120#define MUL8_C 0
121#define QMUL8_C 0
122#define EASE8_C 0
123#define BLEND8_C 0
124#define SCALE8_AVRASM 1
125#define SCALE16BY8_AVRASM 1
126#define SCALE16_AVRASM 1
127#define MUL8_AVRASM 1
128#define QMUL8_AVRASM 1
129#define EASE8_AVRASM 1
130#define CLEANUP_R1_AVRASM 1
131#define BLEND8_AVRASM 1
132#else
133// On ATtiny, we just use C implementations
134#define SCALE8_C 1
135#define SCALE16BY8_C 1
136#define SCALE16_C 1
137#define MUL8_C 1
138#define QMUL8_C 1
139#define EASE8_C 1
140#define BLEND8_C 1
141#define SCALE8_AVRASM 0
142#define SCALE16BY8_AVRASM 0
143#define SCALE16_AVRASM 0
144#define MUL8_AVRASM 0
145#define QMUL8_AVRASM 0
146#define EASE8_AVRASM 0
147#define BLEND8_AVRASM 0
148#endif // end of !defined(LIB8_ATTINY)
149
150// end of #elif defined(__AVR__)
151
152#else
153
154// Doxygen: ignore these macros
156
157// unspecified architecture, so
158// no ASM, everything in C
159#define QADD8_C 1
160#define QADD7_C 1
161#define QSUB8_C 1
162#define SCALE8_C 1
163#define SCALE16BY8_C 1
164#define SCALE16_C 1
165#define ABS8_C 1
166#define MUL8_C 1
167#define QMUL8_C 1
168#define ADD8_C 1
169#define SUB8_C 1
170#define EASE8_C 1
171#define AVG8_C 1
172#define AVG8R_C 1
173#define AVG7_C 1
174#define AVG16_C 1
175#define AVG16R_C 1
176#define AVG15_C 1
177#define BLEND8_C 1
178
180
181#endif
182
373
374
375
376
377#include "lib8tion/math8.h"
378#include "lib8tion/scale8.h"
379#include "lib8tion/random8.h"
380#include "lib8tion/trig8.h"
381
383
384
385
386
387FASTLED_NAMESPACE_BEGIN
388
389
396
398LIB8STATIC float sfract15ToFloat( sfract15 y)
399{
400 return y / 32768.0;
401}
402
406LIB8STATIC sfract15 floatToSfract15( float f)
407{
408 return f * 32768.0;
409}
410
412
413
414
421
422#if defined(__AVR__) || defined(FASTLED_DOXYGEN)
423extern "C" {
424void * memmove8( void * dst, const void * src, uint16_t num );
425void * memcpy8 ( void * dst, const void * src, uint16_t num ) __attribute__ ((noinline));
426void * memset8 ( void * ptr, uint8_t value, uint16_t num ) __attribute__ ((noinline)) ;
427}
428#else
429// on non-AVR platforms, these names just call standard libc.
430#define memmove8 memmove
431#define memcpy8 memcpy
432#define memset8 memset
433#endif
434
436
437
452
455LIB8STATIC uint8_t lerp8by8( uint8_t a, uint8_t b, fract8 frac)
456{
457 uint8_t result;
458 if( b > a) {
459 uint8_t delta = b - a;
460 uint8_t scaled = scale8( delta, frac);
461 result = a + scaled;
462 } else {
463 uint8_t delta = a - b;
464 uint8_t scaled = scale8( delta, frac);
465 result = a - scaled;
466 }
467 return result;
468}
469
472LIB8STATIC uint16_t lerp16by16( uint16_t a, uint16_t b, fract16 frac)
473{
474 uint16_t result;
475 if( b > a ) {
476 uint16_t delta = b - a;
477 uint16_t scaled = scale16(delta, frac);
478 result = a + scaled;
479 } else {
480 uint16_t delta = a - b;
481 uint16_t scaled = scale16( delta, frac);
482 result = a - scaled;
483 }
484 return result;
485}
486
489LIB8STATIC uint16_t lerp16by8( uint16_t a, uint16_t b, fract8 frac)
490{
491 uint16_t result;
492 if( b > a) {
493 uint16_t delta = b - a;
494 uint16_t scaled = scale16by8( delta, frac);
495 result = a + scaled;
496 } else {
497 uint16_t delta = a - b;
498 uint16_t scaled = scale16by8( delta, frac);
499 result = a - scaled;
500 }
501 return result;
502}
503
506LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac)
507{
508 int16_t result;
509 if( b > a) {
510 uint16_t delta = b - a;
511 uint16_t scaled = scale16by8( delta, frac);
512 result = a + scaled;
513 } else {
514 uint16_t delta = a - b;
515 uint16_t scaled = scale16by8( delta, frac);
516 result = a - scaled;
517 }
518 return result;
519}
520
523LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac)
524{
525 int16_t result;
526 if( b > a) {
527 uint16_t delta = b - a;
528 uint16_t scaled = scale16( delta, frac);
529 result = a + scaled;
530 } else {
531 uint16_t delta = a - b;
532 uint16_t scaled = scale16( delta, frac);
533 result = a - scaled;
534 }
535 return result;
536}
537
559LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
560{
561 uint8_t rangeWidth = rangeEnd - rangeStart;
562 uint8_t out = scale8( in, rangeWidth);
563 out += rangeStart;
564 return out;
565}
566
568
569
576
579#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
580LIB8STATIC uint8_t ease8InOutQuad( uint8_t i)
581{
582 uint8_t j = i;
583 if( j & 0x80 ) {
584 j = 255 - j;
585 }
586 uint8_t jj = scale8( j, j);
587 uint8_t jj2 = jj << 1;
588 if( i & 0x80 ) {
589 jj2 = 255 - jj2;
590 }
591 return jj2;
592}
593
594#elif EASE8_AVRASM == 1
595// This AVR asm version of ease8InOutQuad preserves one more
596// low-bit of precision than the C version, and is also slightly
597// smaller and faster.
598LIB8STATIC uint8_t ease8InOutQuad(uint8_t val) {
599 uint8_t j=val;
600 asm volatile (
601 "sbrc %[val], 7 \n"
602 "com %[j] \n"
603 "mul %[j], %[j] \n"
604 "add r0, %[j] \n"
605 "ldi %[j], 0 \n"
606 "adc %[j], r1 \n"
607 "lsl r0 \n" // carry = high bit of low byte of mul product
608 "rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision
609 "sbrc %[val], 7 \n"
610 "com %[j] \n"
611 "clr __zero_reg__ \n"
612 : [j] "+&a" (j)
613 : [val] "a" (val)
614 : "r0", "r1"
615 );
616 return j;
617}
618
619#else
620#error "No implementation for ease8InOutQuad available."
621#endif
622
625LIB8STATIC uint16_t ease16InOutQuad( uint16_t i)
626{
627 uint16_t j = i;
628 if( j & 0x8000 ) {
629 j = 65535 - j;
630 }
631 uint16_t jj = scale16( j, j);
632 uint16_t jj2 = jj << 1;
633 if( i & 0x8000 ) {
634 jj2 = 65535 - jj2;
635 }
636 return jj2;
637}
638
639
643{
644 uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i);
645 uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i);
646
647 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
648
649 /* the code generated for the above *'s automatically
650 cleans up R1, so there's no need to explicitily call
651 cleanup_R1(); */
652
653 uint8_t result = r1;
654
655 // if we got "256", return 255:
656 if( r1 & 0x100 ) {
657 result = 255;
658 }
659 return result;
660}
661
662
670#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
672{
673 if( i < 64) {
674 // start with slope 0.5
675 i /= 2;
676 } else if( i > (255 - 64)) {
677 // end with slope 0.5
678 i = 255 - i;
679 i /= 2;
680 i = 255 - i;
681 } else {
682 // in the middle, use slope 192/128 = 1.5
683 i -= 64;
684 i += (i / 2);
685 i += 32;
686 }
687
688 return i;
689}
690
691#elif EASE8_AVRASM == 1
692LIB8STATIC uint8_t ease8InOutApprox( fract8 i)
693{
694 // takes around 7 cycles on AVR
695 asm volatile (
696 " subi %[i], 64 \n\t"
697 " cpi %[i], 128 \n\t"
698 " brcc Lshift_%= \n\t"
699
700 // middle case
701 " mov __tmp_reg__, %[i] \n\t"
702 " lsr __tmp_reg__ \n\t"
703 " add %[i], __tmp_reg__ \n\t"
704 " subi %[i], 224 \n\t"
705 " rjmp Ldone_%= \n\t"
706
707 // start or end case
708 "Lshift_%=: \n\t"
709 " lsr %[i] \n\t"
710 " subi %[i], 96 \n\t"
711
712 "Ldone_%=: \n\t"
713
714 : [i] "+a" (i)
715 :
716 : "r0"
717 );
718 return i;
719}
720#else
721#error "No implementation for ease8 available."
722#endif
723
725
726
733
734
746LIB8STATIC uint8_t triwave8(uint8_t in)
747{
748 if( in & 0x80) {
749 in = 255 - in;
750 }
751 uint8_t out = in << 1;
752 return out;
753}
754
765LIB8STATIC uint8_t quadwave8(uint8_t in)
766{
767 return ease8InOutQuad( triwave8( in));
768}
769
773LIB8STATIC uint8_t cubicwave8(uint8_t in)
774{
775 return ease8InOutCubic( triwave8( in));
776}
777
778
802LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth=128)
803{
804 if( in < pulsewidth || (pulsewidth == 255)) {
805 return 255;
806 } else {
807 return 0;
808 }
809}
810
812
813
814
815
817
819
820
827
828#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
829// Forward declaration of Arduino function 'millis'.
830//uint32_t millis();
831
842#define GET_MILLIS millis
843#else
844uint32_t get_millisecond_timer();
845#define GET_MILLIS get_millisecond_timer
846#endif
847
849
850
853
854
893
894
902LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase = 0)
903{
904 // BPM is 'beats per minute', or 'beats per 60000ms'.
905 // To avoid using the (slower) division operator, we
906 // want to convert 'beats per 60000ms' to 'beats per 65536ms',
907 // and then use a simple, fast bit-shift to divide by 65536.
908 //
909 // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256.
910 // The conversion is accurate to about 0.05%, more or less,
911 // e.g. if you ask for "120 BPM", you'll get about "119.93".
912 return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
913}
914
918LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase = 0)
919{
920 // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed
921 if( beats_per_minute < 256) beats_per_minute <<= 8;
922 return beat88(beats_per_minute, timebase);
923}
924
928LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase = 0)
929{
930 return beat16( beats_per_minute, timebase) >> 8;
931}
932
933
944LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
945 uint32_t timebase = 0, uint16_t phase_offset = 0)
946{
947 uint16_t beat = beat88( beats_per_minute_88, timebase);
948 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
949 uint16_t rangewidth = highest - lowest;
950 uint16_t scaledbeat = scale16( beatsin, rangewidth);
951 uint16_t result = lowest + scaledbeat;
952 return result;
953}
954
962LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
963 uint32_t timebase = 0, uint16_t phase_offset = 0)
964{
965 uint16_t beat = beat16( beats_per_minute, timebase);
966 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
967 uint16_t rangewidth = highest - lowest;
968 uint16_t scaledbeat = scale16( beatsin, rangewidth);
969 uint16_t result = lowest + scaledbeat;
970 return result;
971}
972
980LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
981 uint32_t timebase = 0, uint8_t phase_offset = 0)
982{
983 uint8_t beat = beat8( beats_per_minute, timebase);
984 uint8_t beatsin = sin8( beat + phase_offset);
985 uint8_t rangewidth = highest - lowest;
986 uint8_t scaledbeat = scale8( beatsin, rangewidth);
987 uint8_t result = lowest + scaledbeat;
988 return result;
989}
990
992
994
995
1000
1003LIB8STATIC uint16_t seconds16()
1004{
1005 uint32_t ms = GET_MILLIS();
1006 uint16_t s16;
1007 s16 = ms / 1000;
1008 return s16;
1009}
1010
1013LIB8STATIC uint16_t minutes16()
1014{
1015 uint32_t ms = GET_MILLIS();
1016 uint16_t m16;
1017 m16 = (ms / (60000L)) & 0xFFFF;
1018 return m16;
1019}
1020
1023LIB8STATIC uint8_t hours8()
1024{
1025 uint32_t ms = GET_MILLIS();
1026 uint8_t h8;
1027 h8 = (ms / (3600000L)) & 0xFF;
1028 return h8;
1029}
1030
1031
1045LIB8STATIC uint16_t div1024_32_16( uint32_t in32)
1046{
1047 uint16_t out16;
1048#if defined(__AVR__)
1049 asm volatile (
1050 " lsr %D[in] \n\t"
1051 " ror %C[in] \n\t"
1052 " ror %B[in] \n\t"
1053 " lsr %D[in] \n\t"
1054 " ror %C[in] \n\t"
1055 " ror %B[in] \n\t"
1056 " mov %B[out],%C[in] \n\t"
1057 " mov %A[out],%B[in] \n\t"
1058 : [in] "+r" (in32),
1059 [out] "=r" (out16)
1060 );
1061#else
1062 out16 = (in32 >> 10) & 0xFFFF;
1063#endif
1064 return out16;
1065}
1066
1070LIB8STATIC uint16_t bseconds16()
1071{
1072 uint32_t ms = GET_MILLIS();
1073 uint16_t s16;
1074 s16 = div1024_32_16( ms);
1075 return s16;
1076}
1077
1081#if 1
1082#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1083class NAME { \
1084public: \
1085 TIMETYPE mPrevTrigger; \
1086 TIMETYPE mPeriod; \
1087 \
1088 NAME() { reset(); mPeriod = 1; }; \
1089 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
1090 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
1091 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
1092 TIMETYPE getPeriod() { return mPeriod; }; \
1093 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
1094 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
1095 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
1096 bool ready() { \
1097 bool isReady = (getElapsed() >= mPeriod); \
1098 if( isReady ) { reset(); } \
1099 return isReady; \
1100 } \
1101 void reset() { mPrevTrigger = getTime(); }; \
1102 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1103 \
1104 operator bool() { return ready(); } \
1105};
1106
1111
1112#if defined(FASTLED_DOXYGEN)
1126public:
1127 TIMETYPE mPrevTrigger;
1128 TIMETYPE mPeriod;
1129
1134 CEveryNTime(TIMETYPE period) { reset(); setPeriod(period); };
1135
1137 void setPeriod( TIMETYPE period) { mPeriod = period; };
1138
1140 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); };
1141
1143 TIMETYPE getPeriod() { return mPeriod; };
1144
1146 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; }
1147
1149 TIMETYPE getRemaining() { return mPeriod - getElapsed(); }
1150
1152 TIMETYPE getLastTriggerTime() { return mPrevTrigger; }
1153
1155 bool ready() {
1156 bool isReady = (getElapsed() >= mPeriod);
1157 if( isReady ) { reset(); }
1158 return isReady;
1159 }
1160
1162 void reset() { mPrevTrigger = getTime(); };
1163
1166
1168 operator bool() { return ready(); }
1169};
1170#endif // FASTLED_DOXYGEN
1171
1174
1177
1180
1183
1186
1188#define CEveryNMilliseconds CEveryNMillis
1189
1192public:
1193 uint32_t mPrevTrigger;
1194 uint32_t mPeriod;
1195
1196 CEveryNMillisDynamic(uint32_t period) : mPeriod(period) { reset(); };
1197 uint32_t getTime() { return GET_MILLIS(); };
1198 uint32_t getPeriod() const { return mPeriod; };
1199 uint32_t getElapsed() { return getTime() - mPrevTrigger; }
1200 uint32_t getRemaining() { return getPeriod() - getElapsed(); }
1201 uint32_t getLastTriggerTime() { return mPrevTrigger; }
1202 bool ready() {
1203 bool isReady = (getElapsed() >= getPeriod());
1204 if( isReady ) { reset(); }
1205 return isReady;
1206 }
1207 void reset() { mPrevTrigger = getTime(); };
1208 void trigger() { mPrevTrigger = getTime() - getPeriod(); };
1209 void setPeriod(uint32_t period) { mPeriod = period; }
1210
1211 operator bool() { return ready(); }
1212};
1214
1215#else
1216
1217// Under C++11 rules, we would be allowed to use not-external
1218// -linkage-type symbols as template arguments,
1219// e.g., LIB8STATIC seconds16, and we'd be able to use these
1220// templates as shown below.
1221// However, under C++03 rules, we cannot do that, and thus we
1222// have to resort to the preprocessor to 'instantiate' 'templates',
1223// as handled above.
1224template<typename timeType,timeType (*timeGetter)()>
1225class CEveryNTimePeriods {
1226public:
1227 timeType mPrevTrigger;
1228 timeType mPeriod;
1229
1230 CEveryNTimePeriods() { reset(); mPeriod = 1; };
1231 CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
1232 void setPeriod( timeType period) { mPeriod = period; };
1233 timeType getTime() { return (timeType)(timeGetter()); };
1234 timeType getPeriod() { return mPeriod; };
1235 timeType getElapsed() { return getTime() - mPrevTrigger; }
1236 timeType getRemaining() { return mPeriod - getElapsed(); }
1237 timeType getLastTriggerTime() { return mPrevTrigger; }
1238 bool ready() {
1239 bool isReady = (getElapsed() >= mPeriod);
1240 if( isReady ) { reset(); }
1241 return isReady;
1242 }
1243 void reset() { mPrevTrigger = getTime(); };
1244 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1245
1246 operator bool() { return ready(); }
1247};
1248typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;
1249typedef CEveryNTimePeriods<uint16_t,bseconds16> CEveryNBSeconds;
1250typedef CEveryNTimePeriods<uint32_t,millis> CEveryNMillis;
1251typedef CEveryNTimePeriods<uint16_t,minutes16> CEveryNMinutes;
1252typedef CEveryNTimePeriods<uint8_t,hours8> CEveryNHours;
1253#endif
1254
1255
1270
1272#define CONCAT_HELPER( x, y ) x##y
1273#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1275
1276
1279#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1280
1283#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1284
1285
1288#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1289
1292#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1293
1294
1297#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1298
1301#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1302
1303
1306#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1307
1310#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1311
1312
1315#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1316
1319#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1320
1321
1323#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1325#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1326
1328#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1329
1331#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1332 static CEveryNMillisDynamic NAME(1); \
1333 NAME.setPeriod(PERIOD_FUNC); \
1334 if( NAME )
1335
1338
1339
1340// These defines are used to declare hidden or commented symbols for the
1341// purposes of Doxygen documentation generation. They do not affect your program.
1342#ifdef FASTLED_DOXYGEN
1346#define USE_GET_MILLISECOND_TIMER
1347#endif
1348
1349FASTLED_NAMESPACE_END
1350
1351#endif
central include file for FastLED, defines the CFastLED class/object
Create the CEveryNMillisDynamic class for dynamic millisecond intervals.
Definition lib8tion.h:1191
Time interval checking class.
Definition lib8tion.h:1125
void trigger()
Reset the timestamp so it is ready() on next call.
Definition lib8tion.h:1165
TIMETYPE mPeriod
Timing interval to check.
Definition lib8tion.h:1128
CEveryNTime(TIMETYPE period)
Constructor.
Definition lib8tion.h:1134
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
Definition lib8tion.h:1152
CEveryNTime()
Default constructor.
Definition lib8tion.h:1131
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
Definition lib8tion.h:1140
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
Definition lib8tion.h:1146
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
Definition lib8tion.h:1137
bool ready()
Check if the time interval has elapsed.
Definition lib8tion.h:1155
void reset()
Reset the timestamp to the current time.
Definition lib8tion.h:1162
TIMETYPE getPeriod()
Get the time interval between triggers.
Definition lib8tion.h:1143
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
Definition lib8tion.h:1127
TIMETYPE getRemaining()
Get the time until the next trigger event.
Definition lib8tion.h:1149
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:928
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:902
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:962
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:918
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:980
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:944
LIB8STATIC uint16_t ease16InOutQuad(uint16_t i)
16-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:625
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
Definition lib8tion.h:671
LIB8STATIC uint8_t ease8InOutQuad(uint8_t i)
8-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:580
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
Definition lib8tion.h:642
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:406
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
Definition lib8tion.h:398
int16_t sfract15
ANSI: signed _Fract.
Definition types.h:49
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition types.h:52
uint8_t fract8
ANSI: unsigned short _Fract.
Definition types.h:30
uint16_t fract16
ANSI: unsigned _Fract.
Definition types.h:40
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:455
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:472
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:489
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:506
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:523
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:559
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:170
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:540
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:468
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:34
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
Definition lib8tion.h:1082
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
Definition lib8tion.h:1013
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:1070
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:842
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:1045
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
Definition lib8tion.h:1023
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
Definition lib8tion.h:1003
#define sin16
Platform-independent alias of the fast sin implementation.
Definition trig8.h:91
#define sin8
Platform-independent alias of the fast sin implementation.
Definition trig8.h:207
LIB8STATIC uint8_t cubicwave8(uint8_t in)
Cubic waveform generator.
Definition lib8tion.h:773
LIB8STATIC uint8_t squarewave8(uint8_t in, uint8_t pulsewidth=128)
Square wave generator.
Definition lib8tion.h:802
LIB8STATIC uint8_t quadwave8(uint8_t in)
Quadratic waveform generator.
Definition lib8tion.h:765
LIB8STATIC uint8_t triwave8(uint8_t in)
Triangle wave generator.
Definition lib8tion.h:746
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...