1#ifndef __INC_LIB8TION_H
2#define __INC_LIB8TION_H
6#ifndef __INC_LED_SYSDEFS_H
7#error WTH? led_sysdefs needs to be included first
15FASTLED_NAMESPACE_BEGIN
21#define LIB8STATIC __attribute__ ((unused)) static inline
23#define LIB8STATIC_ALWAYS_INLINE __attribute__ ((always_inline)) static inline
32#if defined(FASTLED_TEENSY3)
36#define QADD8_ARM_DSP_ASM 1
37#define QADD7_ARM_DSP_ASM 1
64#elif defined(ARDUINO_ARCH_APOLLO3)
106#define QADD8_AVRASM 1
107#define QADD7_AVRASM 1
108#define QSUB8_AVRASM 1
113#define AVG8R_AVRASM 1
115#define AVG16_AVRASM 1
116#define AVG16R_AVRASM 1
117#define AVG15_AVRASM 1
121#if !defined(LIB8_ATTINY)
123#define SCALE16BY8_C 0
129#define SCALE8_AVRASM 1
130#define SCALE16BY8_AVRASM 1
131#define SCALE16_AVRASM 1
133#define QMUL8_AVRASM 1
134#define EASE8_AVRASM 1
135#define CLEANUP_R1_AVRASM 1
136#define BLEND8_AVRASM 1
140#define SCALE16BY8_C 1
146#define SCALE8_AVRASM 0
147#define SCALE16BY8_AVRASM 0
148#define SCALE16_AVRASM 0
150#define QMUL8_AVRASM 0
151#define EASE8_AVRASM 0
152#define BLEND8_AVRASM 0
168#define SCALE16BY8_C 1
499#if defined(__AVR__) || defined(FASTLED_DOXYGEN)
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)) ;
507#define memmove8 memmove
508#define memcpy8 memcpy
509#define memset8 memset
536 uint8_t delta = b - a;
537 uint8_t scaled =
scale8( delta, frac);
540 uint8_t delta = a - b;
541 uint8_t scaled =
scale8( delta, frac);
553 uint16_t delta = b - a;
554 uint16_t scaled =
scale16(delta, frac);
557 uint16_t delta = a - b;
558 uint16_t scaled =
scale16( delta, frac);
570 uint16_t delta = b - a;
574 uint16_t delta = a - b;
587 uint16_t delta = b - a;
591 uint16_t delta = a - b;
604 uint16_t delta = b - a;
605 uint16_t scaled =
scale16( delta, frac);
608 uint16_t delta = a - b;
609 uint16_t scaled =
scale16( delta, frac);
638 uint8_t rangeWidth = rangeEnd - rangeStart;
639 uint8_t out =
scale8( in, rangeWidth);
656#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
663 uint8_t jj =
scale8( j, j);
664 uint8_t jj2 = jj << 1;
671#elif EASE8_AVRASM == 1
688 "clr __zero_reg__ \n"
697#error "No implementation for ease8InOutQuad available."
709 uint16_t jj2 = jj << 1;
724 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
747#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
753 }
else if( i > (255 - 64)) {
768#elif EASE8_AVRASM == 1
773 " subi %[i], 64 \n\t"
774 " cpi %[i], 128 \n\t"
775 " brcc Lshift_%= \n\t"
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"
787 " subi %[i], 96 \n\t"
798#error "No implementation for ease8 available."
828 uint8_t out = in << 1;
881 if( in < pulsewidth || (pulsewidth == 255)) {
899template<
class T,
int F,
int I>
class q {
904 q(
float fx) { i = fx; f = (fx-i) * (1<<F); }
906 q(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
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); }
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; }
951#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
965#define GET_MILLIS millis
967uint32_t get_millisecond_timer();
968#define GET_MILLIS get_millisecond_timer
1035 return (((
GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
1044 if( beats_per_minute < 256) beats_per_minute <<= 8;
1045 return beat88(beats_per_minute, timebase);
1053 return beat16( beats_per_minute, timebase) >> 8;
1068 uint32_t timebase = 0, uint16_t phase_offset = 0)
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;
1086 uint32_t timebase = 0, uint16_t phase_offset = 0)
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;
1104 uint32_t timebase = 0, uint8_t phase_offset = 0)
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;
1140 m16 = (ms / (60000L)) & 0xFFFF;
1150 h8 = (ms / (3600000L)) & 0xFF;
1179 " mov %B[out],%C[in] \n\t"
1180 " mov %A[out],%B[in] \n\t"
1185 out16 = (in32 >> 10) & 0xFFFF;
1205#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1208 TIMETYPE mPrevTrigger; \
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; } \
1220 bool isReady = (getElapsed() >= mPeriod); \
1221 if( isReady ) { reset(); } \
1224 void reset() { mPrevTrigger = getTime(); }; \
1225 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1227 operator bool() { return ready(); } \
1235#if defined(FASTLED_DOXYGEN)
1263 TIMETYPE
getTime() {
return (TIMETYPE)(TIMEGETTER()); };
1280 if( isReady ) {
reset(); }
1311#define CEveryNMilliseconds CEveryNMillis
1323template<
typename timeType,timeType (*timeGetter)()>
1324class CEveryNTimePeriods {
1326 timeType mPrevTrigger;
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; }
1338 bool isReady = (getElapsed() >= mPeriod);
1339 if( isReady ) { reset(); }
1342 void reset() { mPrevTrigger = getTime(); };
1343 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1345 operator bool() {
return ready(); }
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;
1371#define CONCAT_HELPER( x, y ) x##y
1372#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1378#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1382#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1387#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1391#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1396#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1400#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1405#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1409#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1414#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1418#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1422#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1424#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1432#ifdef FASTLED_DOXYGEN
1436#define USE_GET_MILLISECOND_TIMER
1439FASTLED_NAMESPACE_END
central include file for FastLED, defines the CFastLED class/object
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.
Template class for representing fractional ints.
int16_t operator*(int16_t v)
Multiply the fractional int by a value.
uint32_t operator*(uint32_t v)
Multiply the fractional int by a value.
q(float fx)
Constructor, storing a float as a fractional int.
uint16_t operator*(uint16_t v)
Multiply the fractional int by a value.
int32_t operator*(int32_t v)
Multiply the fractional int by a value.
q(uint8_t _i, uint8_t _f)
Constructor, storing a fractional int directly.
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.
q< uint16_t, 12, 4 > q124
A 12.4 integer (12 bits integer, 4 bits fraction)
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
uint8_t fract8
ANSI: unsigned short _Fract.
uint16_t accum124
no direct ANSI counterpart. 12 bits int, 4 bits fraction
int8_t sfract7
ANSI: signed short _Fract.
q< uint8_t, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
int16_t saccum78
ANSI: signed short _Accum. 7 bits int, 8 bits fraction.
int32_t saccum114
no direct ANSI counterpart. 1 bit int, 14 bits fraction
uint16_t fract16
ANSI: unsigned _Fract.
int32_t saccum1516
ANSI: signed _Accum. 15 bits int, 16 bits fraction.
q< uint16_t, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits fraction)
uint32_t accum1616
ANSI: signed _Accum. 16 bits int, 16 bits fraction.
q< uint8_t, 6, 2 > q62
A 6.2 integer (6 bits integer, 2 bits fraction)
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.
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
uint32_t mantissa
23-bit mantissa
uint32_t mant_hi16_exp_lo1
uint32_t i
raw value, as an integer
float f
raw value, as a float
uint32_t exponent
8-bit exponent