1#ifndef __INC_LIB8TION_H
2#define __INC_LIB8TION_H
7#ifndef __INC_LED_SYSDEFS_H
8#error WTH? led_sysdefs needs to be included first
17#include "lib8tion/qfx.h"
27#if defined(FASTLED_TEENSY3)
31#define QADD8_ARM_DSP_ASM 1
32#define QADD7_ARM_DSP_ASM 1
59#elif defined(ARDUINO_ARCH_APOLLO3)
101#define QADD8_AVRASM 1
102#define QADD7_AVRASM 1
103#define QSUB8_AVRASM 1
108#define AVG8R_AVRASM 1
110#define AVG16_AVRASM 1
111#define AVG16R_AVRASM 1
112#define AVG15_AVRASM 1
116#if !defined(LIB8_ATTINY)
118#define SCALE16BY8_C 0
124#define SCALE8_AVRASM 1
125#define SCALE16BY8_AVRASM 1
126#define SCALE16_AVRASM 1
128#define QMUL8_AVRASM 1
129#define EASE8_AVRASM 1
130#define CLEANUP_R1_AVRASM 1
131#define BLEND8_AVRASM 1
135#define SCALE16BY8_C 1
141#define SCALE8_AVRASM 0
142#define SCALE16BY8_AVRASM 0
143#define SCALE16_AVRASM 0
145#define QMUL8_AVRASM 0
146#define EASE8_AVRASM 0
147#define BLEND8_AVRASM 0
163#define SCALE16BY8_C 1
422#if defined(__AVR__) || defined(FASTLED_DOXYGEN)
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)) ;
430#define memmove8 memmove
431#define memcpy8 memcpy
432#define memset8 memset
459 uint8_t delta = b - a;
460 uint8_t scaled =
scale8( delta, frac);
463 uint8_t delta = a - b;
464 uint8_t scaled =
scale8( delta, frac);
476 uint16_t delta = b - a;
477 uint16_t scaled =
scale16(delta, frac);
480 uint16_t delta = a - b;
481 uint16_t scaled =
scale16( delta, frac);
493 uint16_t delta = b - a;
497 uint16_t delta = a - b;
510 uint16_t delta = b - a;
514 uint16_t delta = a - b;
527 uint16_t delta = b - a;
528 uint16_t scaled =
scale16( delta, frac);
531 uint16_t delta = a - b;
532 uint16_t scaled =
scale16( delta, frac);
561 uint8_t rangeWidth = rangeEnd - rangeStart;
562 uint8_t out =
scale8( in, rangeWidth);
579#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
586 uint8_t jj =
scale8( j, j);
587 uint8_t jj2 = jj << 1;
594#elif EASE8_AVRASM == 1
611 "clr __zero_reg__ \n"
620#error "No implementation for ease8InOutQuad available."
632 uint16_t jj2 = jj << 1;
647 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
670#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
676 }
else if( i > (255 - 64)) {
691#elif EASE8_AVRASM == 1
696 " subi %[i], 64 \n\t"
697 " cpi %[i], 128 \n\t"
698 " brcc Lshift_%= \n\t"
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"
710 " subi %[i], 96 \n\t"
721#error "No implementation for ease8 available."
751 uint8_t out = in << 1;
804 if( in < pulsewidth || (pulsewidth == 255)) {
823#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
837#define GET_MILLIS millis
839uint32_t get_millisecond_timer();
840#define GET_MILLIS get_millisecond_timer
907 return (((
GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
916 if( beats_per_minute < 256) beats_per_minute <<= 8;
917 return beat88(beats_per_minute, timebase);
925 return beat16( beats_per_minute, timebase) >> 8;
940 uint32_t timebase = 0, uint16_t phase_offset = 0)
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;
958 uint32_t timebase = 0, uint16_t phase_offset = 0)
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;
976 uint32_t timebase = 0, uint8_t phase_offset = 0)
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;
1012 m16 = (ms / (60000L)) & 0xFFFF;
1022 h8 = (ms / (3600000L)) & 0xFF;
1051 " mov %B[out],%C[in] \n\t"
1052 " mov %A[out],%B[in] \n\t"
1057 out16 = (in32 >> 10) & 0xFFFF;
1077#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1080 TIMETYPE mPrevTrigger; \
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; } \
1092 bool isReady = (getElapsed() >= mPeriod); \
1093 if( isReady ) { reset(); } \
1096 void reset() { mPrevTrigger = getTime(); }; \
1097 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1099 operator bool() { return ready(); } \
1107#if defined(FASTLED_DOXYGEN)
1135 TIMETYPE
getTime() {
return (TIMETYPE)(TIMEGETTER()); };
1152 if( isReady ) {
reset(); }
1183#define CEveryNMilliseconds CEveryNMillis
1188 uint32_t mPrevTrigger;
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; }
1198 bool isReady = (getElapsed() >= getPeriod());
1199 if( isReady ) { reset(); }
1202 void reset() { mPrevTrigger = getTime(); };
1203 void trigger() { mPrevTrigger = getTime() - getPeriod(); };
1204 void setPeriod(uint32_t period) { mPeriod = period; }
1206 operator bool() {
return ready(); }
1219template<
typename timeType,timeType (*timeGetter)()>
1220class CEveryNTimePeriods {
1222 timeType mPrevTrigger;
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; }
1234 bool isReady = (getElapsed() >= mPeriod);
1235 if( isReady ) { reset(); }
1238 void reset() { mPrevTrigger = getTime(); };
1239 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1241 operator bool() {
return ready(); }
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;
1267#define CONCAT_HELPER( x, y ) x##y
1268#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1274#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1278#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1283#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1287#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1292#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1296#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1301#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1305#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1310#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1314#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1318#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1320#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1323#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1326#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1327 static CEveryNMillisDynamic NAME(1); \
1328 NAME.setPeriod(PERIOD_FUNC); \
1337#ifdef FASTLED_DOXYGEN
1341#define USE_GET_MILLISECOND_TIMER
central include file for FastLED, defines the CFastLED class/object
Create the CEveryNMillisDynamic class for dynamic millisecond intervals.
Time interval checking class.
void trigger()
Reset the timestamp so it is ready() on next call.
TIMETYPE mPeriod
Timing interval to check.
CEveryNTime(TIMETYPE period)
Constructor.
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
CEveryNTime()
Default constructor.
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
bool ready()
Check if the time interval has elapsed.
void reset()
Reset the timestamp to the current time.
TIMETYPE getPeriod()
Get the time interval between triggers.
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
TIMETYPE getRemaining()
Get the time until the next trigger event.
LIB8STATIC uint8_t beat8(accum88 beats_per_minute, uint32_t timebase=0)
Generates an 8-bit "sawtooth" wave at a given BPM.
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.
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.
LIB8STATIC uint16_t beat16(accum88 beats_per_minute, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM.
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.
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.
LIB8STATIC uint16_t ease16InOutQuad(uint16_t i)
16-bit quadratic ease-in / ease-out function.
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
LIB8STATIC uint8_t ease8InOutQuad(uint8_t i)
8-bit quadratic ease-in / ease-out function.
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
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).
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
int16_t sfract15
ANSI: signed _Fract.
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
uint8_t fract8
ANSI: unsigned short _Fract.
uint16_t fract16
ANSI: unsigned _Fract.
LIB8STATIC uint8_t lerp8by8(uint8_t a, uint8_t b, fract8 frac)
Linear interpolation between two unsigned 8-bit values, with 8-bit fraction.
LIB8STATIC uint16_t lerp16by16(uint16_t a, uint16_t b, fract16 frac)
Linear interpolation between two unsigned 16-bit values, with 16-bit fraction.
LIB8STATIC uint16_t lerp16by8(uint16_t a, uint16_t b, fract8 frac)
Linear interpolation between two unsigned 16-bit values, with 8-bit fraction.
LIB8STATIC int16_t lerp15by8(int16_t a, int16_t b, fract8 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
LIB8STATIC int16_t lerp15by16(int16_t a, int16_t b, fract16 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
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.
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.
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...
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...
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 ...
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
LIB8STATIC uint16_t bseconds16()
Returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a second lon...
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
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.
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
#define sin16
Platform-independent alias of the fast sin implementation.
#define sin8
Platform-independent alias of the fast sin implementation.
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
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.
#define FASTLED_NAMESPACE_BEGIN
Start of the FastLED namespace.
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...