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
10 FASTLED_NAMESPACE_BEGIN
178 #define LIB8STATIC __attribute__ ((unused)) static inline
179 #define LIB8STATIC_ALWAYS_INLINE __attribute__ ((always_inline)) static inline
181 #if !defined(__AVR__)
186 #if defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__)
187 #define LIB8_ATTINY 1
193 #if defined(FASTLED_TEENSY3)
197 #define QADD8_ARM_DSP_ASM 1
198 #define QADD7_ARM_DSP_ASM 1
207 #define SCALE16BY8_C 1
221 #elif defined(__AVR__)
236 #define QADD8_AVRASM 1
237 #define QADD7_AVRASM 1
238 #define QSUB8_AVRASM 1
239 #define ABS8_AVRASM 1
240 #define ADD8_AVRASM 1
241 #define SUB8_AVRASM 1
242 #define AVG8_AVRASM 1
243 #define AVG7_AVRASM 1
244 #define AVG16_AVRASM 1
245 #define AVG15_AVRASM 1
249 #if !defined(LIB8_ATTINY)
251 #define SCALE16BY8_C 0
256 #define SCALE8_AVRASM 1
257 #define SCALE16BY8_AVRASM 1
258 #define SCALE16_AVRASM 1
259 #define MUL8_AVRASM 1
260 #define QMUL8_AVRASM 1
261 #define EASE8_AVRASM 1
262 #define CLEANUP_R1_AVRASM 1
266 #define SCALE16BY8_C 1
271 #define SCALE8_AVRASM 0
272 #define SCALE16BY8_AVRASM 0
273 #define SCALE16_AVRASM 0
274 #define MUL8_AVRASM 0
275 #define QMUL8_AVRASM 0
276 #define EASE8_AVRASM 0
287 #define SCALE16BY8_C 1
367 uint32_t mantissa: 23;
368 uint32_t exponent: 8;
378 uint32_t mant_lo8 : 8;
379 uint32_t mant_hi16_exp_lo1 : 16;
380 uint32_t sb_exphi7 : 8;
384 #include "lib8tion/math8.h"
385 #include "lib8tion/scale8.h"
386 #include "lib8tion/random8.h"
387 #include "lib8tion/trig8.h"
429 void * memmove8(
void * dst,
const void * src, uint16_t num );
430 void * memcpy8 (
void * dst,
const void * src, uint16_t num )
__attribute__ ((noinline));
431 void * memset8 (
void * ptr, uint8_t value, uint16_t num )
__attribute__ ((noinline)) ;
435 #define memmove8 memmove
436 #define memcpy8 memcpy
437 #define memset8 memset
461 uint8_t delta = b - a;
462 uint8_t scaled =
scale8( delta, frac);
465 uint8_t delta = a - b;
466 uint8_t scaled =
scale8( delta, frac);
478 uint16_t delta = b - a;
479 uint32_t scaled =
scale16(delta, frac);
482 uint16_t delta = a - b;
483 uint16_t scaled =
scale16( delta, frac);
495 uint16_t delta = b - a;
499 uint16_t delta = a - b;
512 uint16_t delta = b - a;
516 uint16_t delta = a - b;
529 uint16_t delta = b - a;
530 uint16_t scaled =
scale16( delta, frac);
533 uint16_t delta = a - b;
534 uint16_t scaled =
scale16( delta, frac);
557 LIB8STATIC uint8_t
map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
559 uint8_t rangeWidth = rangeEnd - rangeStart;
560 uint8_t out =
scale8( in, rangeWidth);
579 uint8_t jj =
scale8( j, (j+1));
580 uint8_t jj2 = jj << 1;
595 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
624 }
else if( i > (255 - 64)) {
639 #elif EASE8_AVRASM == 1
644 " subi %[i], 64 \n\t"
645 " cpi %[i], 128 \n\t"
646 " brcc Lshift_%= \n\t"
649 " mov __tmp_reg__, %[i] \n\t"
650 " lsr __tmp_reg__ \n\t"
651 " add %[i], __tmp_reg__ \n\t"
652 " subi %[i], 224 \n\t"
653 " rjmp Ldone_%= \n\t"
658 " subi %[i], 96 \n\t"
669 #error "No implementation for ease8 available."
689 uint8_t out = in << 1;
741 LIB8STATIC uint8_t
squarewave8( uint8_t in, uint8_t pulsewidth=128)
743 if( in < pulsewidth || (pulsewidth == 255)) {
754 template<
class T,
int F,
int I>
class q {
758 q(
float fx) { i = fx; f = (fx-i) * (1<<F); }
759 q(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
760 uint32_t operator*(uint32_t v) {
return (v*i) + ((v*f)>>F); }
761 uint16_t operator*(uint16_t v) {
return (v*i) + ((v*f)>>F); }
762 int32_t operator*(int32_t v) {
return (v*i) + ((v*f)>>F); }
763 int16_t operator*(int16_t v) {
return (v*i) + ((v*f)>>F); }
765 int operator*(
int v) {
return (v*i) + ((v*f)>>F); }
769 template<
class T,
int F,
int I>
static uint32_t operator*(uint32_t v,
q<T,F,I> &
q) {
return q * v; }
770 template<
class T,
int F,
int I>
static uint16_t operator*(uint16_t v,
q<T,F,I> &
q) {
return q * v; }
771 template<
class T,
int F,
int I>
static int32_t operator*(int32_t v,
q<T,F,I> &
q) {
return q * v; }
772 template<
class T,
int F,
int I>
static int16_t operator*(int16_t v,
q<T,F,I> &
q) {
return q * v; }
774 template<
class T,
int F,
int I>
static int operator*(
int v,
q<T,F,I> &
q) {
return q * v; }
841 #if (defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)
844 #define GET_MILLIS millis
846 uint32_t get_millisecond_timer();
847 #define GET_MILLIS get_millisecond_timer
855 LIB8STATIC uint16_t
beat88(
accum88 beats_per_minute_88, uint32_t timebase = 0)
865 return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
869 LIB8STATIC uint16_t
beat16(
accum88 beats_per_minute, uint32_t timebase = 0)
872 if( beats_per_minute < 256) beats_per_minute <<= 8;
873 return beat88(beats_per_minute, timebase);
877 LIB8STATIC uint8_t
beat8(
accum88 beats_per_minute, uint32_t timebase = 0)
879 return beat16( beats_per_minute, timebase) >> 8;
888 LIB8STATIC uint16_t
beatsin88(
accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
889 uint32_t timebase = 0, uint16_t phase_offset = 0)
891 uint16_t beat =
beat88( beats_per_minute_88, timebase);
892 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
893 uint16_t rangewidth = highest - lowest;
894 uint16_t scaledbeat =
scale16( beatsin, rangewidth);
895 uint16_t result = lowest + scaledbeat;
901 LIB8STATIC uint16_t
beatsin16(
accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
902 uint32_t timebase = 0, uint16_t phase_offset = 0)
904 uint16_t beat =
beat16( beats_per_minute, timebase);
905 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
906 uint16_t rangewidth = highest - lowest;
907 uint16_t scaledbeat =
scale16( beatsin, rangewidth);
908 uint16_t result = lowest + scaledbeat;
914 LIB8STATIC uint8_t
beatsin8(
accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
915 uint32_t timebase = 0, uint8_t phase_offset = 0)
917 uint8_t beat =
beat8( beats_per_minute, timebase);
918 uint8_t beatsin = sin8( beat + phase_offset);
919 uint8_t rangewidth = highest - lowest;
920 uint8_t scaledbeat =
scale8( beatsin, rangewidth);
921 uint8_t result = lowest + scaledbeat;
930 uint32_t ms = GET_MILLIS();
940 uint32_t ms = GET_MILLIS();
942 m16 = (ms / (60000L)) & 0xFFFF;
950 uint32_t ms = GET_MILLIS();
952 h8 = (ms / (3600000L)) & 0xFF;
978 " mov %B[out],%C[in] \n\t"
979 " mov %A[out],%B[in] \n\t"
984 out16 = (in32 >> 10) & 0xFFFF;
994 uint32_t ms = GET_MILLIS();
1004 #define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1007 TIMETYPE mPrevTrigger; \
1010 NAME() { reset(); mPeriod = 1; }; \
1011 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
1012 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
1013 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
1014 TIMETYPE getPeriod() { return mPeriod; }; \
1015 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
1016 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
1017 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
1019 bool isReady = (getElapsed() >= mPeriod); \
1020 if( isReady ) { reset(); } \
1023 void reset() { mPrevTrigger = getTime(); }; \
1024 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1026 operator bool() { return ready(); } \
1028 INSTANTIATE_EVERY_N_TIME_PERIODS(
CEveryNMillis,uint32_t,GET_MILLIS);
1042 template<
typename timeType,timeType (*timeGetter)()>
1045 timeType mPrevTrigger;
1050 void setPeriod( timeType period) { mPeriod = period; };
1051 timeType getTime() {
return (timeType)(timeGetter()); };
1052 timeType getPeriod() {
return mPeriod; };
1053 timeType getElapsed() {
return getTime() - mPrevTrigger; }
1054 timeType getRemaining() {
return mPeriod - getElapsed(); }
1055 timeType getLastTriggerTime() {
return mPrevTrigger; }
1057 bool isReady = (getElapsed() >= mPeriod);
1058 if( isReady ) { reset(); }
1061 void reset() { mPrevTrigger = getTime(); };
1062 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1064 operator bool() {
return ready(); }
1074 #define CONCAT_HELPER( x, y ) x##y
1075 #define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1076 #define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1077 #define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1078 #define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1079 #define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1080 #define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1081 #define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1082 #define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1083 #define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1084 #define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1085 #define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1087 #define CEveryNMilliseconds CEveryNMillis
1088 #define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1089 #define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1091 FASTLED_NAMESPACE_END
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
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 uint16_t beat16(accum88 beats_per_minute, uint32_t timebase=0)
beat16 generates a 16-bit 'sawtooth' wave at a given BPM
int16_t saccum78
ANSI: signed short _Accum. 7 bits int, 8 bits fraction.
LIB8STATIC uint8_t ease8InOutQuad(uint8_t i)
ease8InOutQuad: 8-bit quadratic ease-in / ease-out function Takes around 13 cycles on AVR ...
uint32_t accum1616
ANSI: signed _Accum. 16 bits int, 16 bits fraction.
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
LIB8STATIC uint8_t lerp8by8(uint8_t a, uint8_t b, fract8 frac)
linear interpolation between two unsigned 8-bit values, with 8-bit fraction
uint16_t fract16
ANSI: unsigned _Fract.
LIB8STATIC uint16_t lerp16by16(uint16_t a, uint16_t b, fract16 frac)
linear interpolation between two unsigned 16-bit values, with 16-bit fraction
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
typedef for IEEE754 "binary32" float type internals
int16_t sfract15
ANSI: signed _Fract.
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)
beatsin16 generates a 16-bit sine wave at a given BPM, that oscillates within a given range...
q< uint16_t, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits 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
int32_t saccum114
no direct ANSI counterpart. 1 bit int, 14 bits fraction
LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale)
scale a 16-bit unsigned value by a 16-bit value, considered as numerator of a fraction whose denomina...
LIB8STATIC sfract15 floatToSfract15(float f)
conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point.
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
uint16_t accum124
no direct ANSI counterpart. 12 bits int, 4 bits fraction
LIB8STATIC uint16_t bseconds16()
bseconds16 returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a...
q< uint16_t, 12, 4 > q124
A 12.4 integer (12 bits integer, 4 bits fraction)
LIB8STATIC uint8_t quadwave8(uint8_t in)
quadwave8: quadratic waveform generator.
uint8_t fract8
ANSI unsigned short _Fract.
q< uint8_t, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
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)
beatsin88 generates a 16-bit sine wave at a given BPM, that oscillates within a given range...
LIB8STATIC uint8_t cubicwave8(uint8_t in)
cubicwave8: cubic waveform generator.
central include file for FastLED, defines the CFastLED class/object
LIB8STATIC uint16_t beat88(accum88 beats_per_minute_88, uint32_t timebase=0)
with BPM specified in Q8.8 fixed-point format; e.g.
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
ease8InOutApprox: fast, rough 8-bit ease-in/ease-out function shaped approximately like 'ease8InOutCu...
int8_t sfract7
ANSI: signed short _Fract.
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
ease8InOutCubic: 8-bit cubic ease-in / ease-out function Takes around 18 cycles on AVR ...
LIB8STATIC uint8_t beat8(accum88 beats_per_minute, uint32_t timebase=0)
beat8 generates an 8-bit 'sawtooth' wave at a given BPM
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
LIB8STATIC uint8_t triwave8(uint8_t in)
triwave8: triangle (sawtooth) wave generator.
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8(uint16_t i, fract8 scale)
scale a 16-bit unsigned value by an 8-bit value, considered as numerator of a fraction whose denomina...
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)
beatsin8 generates an 8-bit sine wave at a given BPM, that oscillates within a given range...
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 ...
LIB8STATIC uint8_t squarewave8(uint8_t in, uint8_t pulsewidth=128)
squarewave8: square wave generator.
LIB8STATIC int16_t lerp15by8(int16_t a, int16_t b, fract8 frac)
linear interpolation between two signed 15-bit values, with 8-bit fraction
q< uint8_t, 6, 2 > q62
A 6.2 integer (6 bits integer, 2 bits fraction)
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 If you are doing several 'scale8's in...
Template class for represneting fractional ints.
LIB8STATIC uint8_t map8(uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
map8: map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of ...
int32_t saccum1516
ANSI: signed _Accum. 15 bits int, 16 bits fraction.
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 float sfract15ToFloat(sfract15 y)
sfract15ToFloat: conversion from sfract15 fixed point to IEEE754 32-bit float.