FastLED 3.9.7
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 "lib8tion/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
388
389
396
399{
400 return y / 32768.0;
401}
402
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
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
814
815
822
823#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
824// Forward declaration of Arduino function 'millis'.
825//uint32_t millis();
826
837#define GET_MILLIS millis
838#else
839uint32_t get_millisecond_timer();
840#define GET_MILLIS get_millisecond_timer
841#endif
842
844
845
848
849
888
889
897LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase = 0)
898{
899 // BPM is 'beats per minute', or 'beats per 60000ms'.
900 // To avoid using the (slower) division operator, we
901 // want to convert 'beats per 60000ms' to 'beats per 65536ms',
902 // and then use a simple, fast bit-shift to divide by 65536.
903 //
904 // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256.
905 // The conversion is accurate to about 0.05%, more or less,
906 // e.g. if you ask for "120 BPM", you'll get about "119.93".
907 return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
908}
909
913LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase = 0)
914{
915 // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed
916 if( beats_per_minute < 256) beats_per_minute <<= 8;
917 return beat88(beats_per_minute, timebase);
918}
919
923LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase = 0)
924{
925 return beat16( beats_per_minute, timebase) >> 8;
926}
927
928
939LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
940 uint32_t timebase = 0, uint16_t phase_offset = 0)
941{
942 uint16_t beat = beat88( beats_per_minute_88, timebase);
943 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
944 uint16_t rangewidth = highest - lowest;
945 uint16_t scaledbeat = scale16( beatsin, rangewidth);
946 uint16_t result = lowest + scaledbeat;
947 return result;
948}
949
957LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
958 uint32_t timebase = 0, uint16_t phase_offset = 0)
959{
960 uint16_t beat = beat16( beats_per_minute, timebase);
961 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
962 uint16_t rangewidth = highest - lowest;
963 uint16_t scaledbeat = scale16( beatsin, rangewidth);
964 uint16_t result = lowest + scaledbeat;
965 return result;
966}
967
975LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
976 uint32_t timebase = 0, uint8_t phase_offset = 0)
977{
978 uint8_t beat = beat8( beats_per_minute, timebase);
979 uint8_t beatsin = sin8( beat + phase_offset);
980 uint8_t rangewidth = highest - lowest;
981 uint8_t scaledbeat = scale8( beatsin, rangewidth);
982 uint8_t result = lowest + scaledbeat;
983 return result;
984}
985
987
989
990
995
999{
1000 uint32_t ms = GET_MILLIS();
1001 uint16_t s16;
1002 s16 = ms / 1000;
1003 return s16;
1004}
1005
1009{
1010 uint32_t ms = GET_MILLIS();
1011 uint16_t m16;
1012 m16 = (ms / (60000L)) & 0xFFFF;
1013 return m16;
1014}
1015
1019{
1020 uint32_t ms = GET_MILLIS();
1021 uint8_t h8;
1022 h8 = (ms / (3600000L)) & 0xFF;
1023 return h8;
1024}
1025
1026
1040LIB8STATIC uint16_t div1024_32_16( uint32_t in32)
1041{
1042 uint16_t out16;
1043#if defined(__AVR__)
1044 asm volatile (
1045 " lsr %D[in] \n\t"
1046 " ror %C[in] \n\t"
1047 " ror %B[in] \n\t"
1048 " lsr %D[in] \n\t"
1049 " ror %C[in] \n\t"
1050 " ror %B[in] \n\t"
1051 " mov %B[out],%C[in] \n\t"
1052 " mov %A[out],%B[in] \n\t"
1053 : [in] "+r" (in32),
1054 [out] "=r" (out16)
1055 );
1056#else
1057 out16 = (in32 >> 10) & 0xFFFF;
1058#endif
1059 return out16;
1060}
1061
1066{
1067 uint32_t ms = GET_MILLIS();
1068 uint16_t s16;
1069 s16 = div1024_32_16( ms);
1070 return s16;
1071}
1072
1076#if 1
1077#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1078class NAME { \
1079public: \
1080 TIMETYPE mPrevTrigger; \
1081 TIMETYPE mPeriod; \
1082 \
1083 NAME() { reset(); mPeriod = 1; }; \
1084 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
1085 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
1086 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
1087 TIMETYPE getPeriod() { return mPeriod; }; \
1088 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
1089 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
1090 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
1091 bool ready() { \
1092 bool isReady = (getElapsed() >= mPeriod); \
1093 if( isReady ) { reset(); } \
1094 return isReady; \
1095 } \
1096 void reset() { mPrevTrigger = getTime(); }; \
1097 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1098 \
1099 operator bool() { return ready(); } \
1100};
1101
1106
1107#if defined(FASTLED_DOXYGEN)
1121public:
1122 TIMETYPE mPrevTrigger;
1123 TIMETYPE mPeriod;
1124
1129 CEveryNTime(TIMETYPE period) { reset(); setPeriod(period); };
1130
1132 void setPeriod( TIMETYPE period) { mPeriod = period; };
1133
1135 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); };
1136
1138 TIMETYPE getPeriod() { return mPeriod; };
1139
1141 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; }
1142
1144 TIMETYPE getRemaining() { return mPeriod - getElapsed(); }
1145
1147 TIMETYPE getLastTriggerTime() { return mPrevTrigger; }
1148
1150 bool ready() {
1151 bool isReady = (getElapsed() >= mPeriod);
1152 if( isReady ) { reset(); }
1153 return isReady;
1154 }
1155
1157 void reset() { mPrevTrigger = getTime(); };
1158
1161
1163 operator bool() { return ready(); }
1164};
1165#endif // FASTLED_DOXYGEN
1166
1169
1172
1175
1178
1181
1183#define CEveryNMilliseconds CEveryNMillis
1184
1187public:
1188 uint32_t mPrevTrigger;
1189 uint32_t mPeriod;
1190
1191 CEveryNMillisDynamic(uint32_t period) : mPeriod(period) { reset(); };
1192 uint32_t getTime() { return GET_MILLIS(); };
1193 uint32_t getPeriod() const { return mPeriod; };
1194 uint32_t getElapsed() { return getTime() - mPrevTrigger; }
1195 uint32_t getRemaining() { return getPeriod() - getElapsed(); }
1196 uint32_t getLastTriggerTime() { return mPrevTrigger; }
1197 bool ready() {
1198 bool isReady = (getElapsed() >= getPeriod());
1199 if( isReady ) { reset(); }
1200 return isReady;
1201 }
1202 void reset() { mPrevTrigger = getTime(); };
1203 void trigger() { mPrevTrigger = getTime() - getPeriod(); };
1204 void setPeriod(uint32_t period) { mPeriod = period; }
1205
1206 operator bool() { return ready(); }
1207};
1209
1210#else
1211
1212// Under C++11 rules, we would be allowed to use not-external
1213// -linkage-type symbols as template arguments,
1214// e.g., LIB8STATIC seconds16, and we'd be able to use these
1215// templates as shown below.
1216// However, under C++03 rules, we cannot do that, and thus we
1217// have to resort to the preprocessor to 'instantiate' 'templates',
1218// as handled above.
1219template<typename timeType,timeType (*timeGetter)()>
1220class CEveryNTimePeriods {
1221public:
1222 timeType mPrevTrigger;
1223 timeType mPeriod;
1224
1225 CEveryNTimePeriods() { reset(); mPeriod = 1; };
1226 CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
1227 void setPeriod( timeType period) { mPeriod = period; };
1228 timeType getTime() { return (timeType)(timeGetter()); };
1229 timeType getPeriod() { return mPeriod; };
1230 timeType getElapsed() { return getTime() - mPrevTrigger; }
1231 timeType getRemaining() { return mPeriod - getElapsed(); }
1232 timeType getLastTriggerTime() { return mPrevTrigger; }
1233 bool ready() {
1234 bool isReady = (getElapsed() >= mPeriod);
1235 if( isReady ) { reset(); }
1236 return isReady;
1237 }
1238 void reset() { mPrevTrigger = getTime(); };
1239 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1240
1241 operator bool() { return ready(); }
1242};
1243typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;
1244typedef CEveryNTimePeriods<uint16_t,bseconds16> CEveryNBSeconds;
1245typedef CEveryNTimePeriods<uint32_t,millis> CEveryNMillis;
1246typedef CEveryNTimePeriods<uint16_t,minutes16> CEveryNMinutes;
1247typedef CEveryNTimePeriods<uint8_t,hours8> CEveryNHours;
1248#endif
1249
1250
1265
1267#define CONCAT_HELPER( x, y ) x##y
1268#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1270
1271
1274#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1275
1278#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1279
1280
1283#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1284
1287#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1288
1289
1292#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1293
1296#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1297
1298
1301#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1302
1305#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1306
1307
1310#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1311
1314#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1315
1316
1318#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1320#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1321
1323#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1324
1326#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1327 static CEveryNMillisDynamic NAME(1); \
1328 NAME.setPeriod(PERIOD_FUNC); \
1329 if( NAME )
1330
1333
1334
1335// These defines are used to declare hidden or commented symbols for the
1336// purposes of Doxygen documentation generation. They do not affect your program.
1337#ifdef FASTLED_DOXYGEN
1341#define USE_GET_MILLISECOND_TIMER
1342#endif
1343
1345
1346#endif
central include file for FastLED, defines the CFastLED class/object
Create the CEveryNMillisDynamic class for dynamic millisecond intervals.
Definition lib8tion.h:1186
Time interval checking class.
Definition lib8tion.h:1120
void trigger()
Reset the timestamp so it is ready() on next call.
Definition lib8tion.h:1160
TIMETYPE mPeriod
Timing interval to check.
Definition lib8tion.h:1123
CEveryNTime(TIMETYPE period)
Constructor.
Definition lib8tion.h:1129
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
Definition lib8tion.h:1147
CEveryNTime()
Default constructor.
Definition lib8tion.h:1126
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
Definition lib8tion.h:1135
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
Definition lib8tion.h:1141
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
Definition lib8tion.h:1132
bool ready()
Check if the time interval has elapsed.
Definition lib8tion.h:1150
void reset()
Reset the timestamp to the current time.
Definition lib8tion.h:1157
TIMETYPE getPeriod()
Get the time interval between triggers.
Definition lib8tion.h:1138
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
Definition lib8tion.h:1122
TIMETYPE getRemaining()
Get the time until the next trigger event.
Definition lib8tion.h:1144
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:923
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:897
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:957
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:913
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:975
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:939
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:55
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition types.h:58
uint8_t fract8
ANSI: unsigned short _Fract.
Definition types.h:36
uint16_t fract16
ANSI: unsigned _Fract.
Definition types.h:46
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:1077
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
Definition lib8tion.h:1008
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:1065
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:837
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:1040
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
Definition lib8tion.h:1018
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
Definition lib8tion.h:998
#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
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8static.h:10
Defines static inlining macros for lib8tion functions.
Defines fractional types used for lib8tion functions.
Fast, efficient 8-bit math functions specifically designed for high-performance LED programming.
#define FASTLED_NAMESPACE_END
End of the FastLED namespace.
Definition namespace.h:16
#define FASTLED_NAMESPACE_BEGIN
Start of the FastLED namespace.
Definition namespace.h:14
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...