FastLED 3.9.15
Loading...
Searching...
No Matches
fl::detail Namespace Reference

Detailed Description

Compile-time linker keep-alive hook for a single fl::Bus.

SFINAE helpers for detecting a static ENCODER member on timing structs.

Used by the legacy FastLED.addLeds<..., fl::Bus B>(...) template path (see #2460). When B != Bus::AUTO, naming BusTraits<B>::instance here is what makes --gc-sections retain the named driver's translation unit even though the legacy controller body never invokes the singleton directly. The Bus::AUTO specialization is a no-op so calls without an explicit Bus param remain byte-for-byte identical to pre-#2460 code.

Namespaces

namespace  anonymous_namespace{allocator.cpp.hpp}
 
namespace  anonymous_namespace{singleton.cpp.hpp}
 
namespace  anonymous_namespace{wait_spin_budget.cpp.hpp}
 
namespace  gamma_constexpr
 

Classes

struct  ActiveLoggerRegistry
 Active logger registry for iteration (flush operations) Only tracks loggers that have been instantiated via template access. More...
 
class  AlphaTrimmedMeanImpl
 
struct  array_delete
 
class  AsyncLoggerServiceTask
 Auto-instantiating task for async logger servicing Registers itself with fl::task::Scheduler when first accessed Only instantiated if at least one async logger is used (linker removes if unused) More...
 
class  AttackDecayFilterImpl
 
struct  AudioLoggerInfo
 
struct  BackgroundFlushState
 
class  BilateralFilterImpl
 
class  BiquadFilterImpl
 
struct  BusKeepAliveImpl
 
struct  BusKeepAliveImpl< fl::Bus::AUTO >
 
struct  CallableHolderBase
 
class  CascadedEMAImpl
 
struct  control_block_alignment
 
struct  ControlBlock
 
struct  ControlBlockBase
 
class  DCBlockerImpl
 
struct  default_delete
 
class  ErasedInvoker
 
class  ErasedSchemaGenerator
 
class  ExponentialSmootherImpl
 
struct  FlexIOLoggerInfo
 
class  GaussianFilterImpl
 
struct  get_encoder
 
struct  get_encoder< CHIPSET, true >
 
class  HampelFilterImpl
 
struct  has_copy_ctor
 
struct  has_copy_ctor< T, decltype(void(T(fl::declval< const T & >())))>
 
struct  has_default_ctor
 
struct  has_default_ctor< T, decltype(void(T()))>
 
struct  has_move_ctor
 
struct  has_move_ctor< T, decltype(void(T(fl::declval< T && >())))>
 
struct  int_to_fixed
 
struct  int_to_fixed< IntBits, FracBits, false >
 
struct  int_to_fixed< IntBits, FracBits, true >
 
struct  integer_digits10_helper
 
struct  integer_digits_helper
 
struct  integer_max_helper
 
struct  integer_max_helper< T, false >
 
struct  integer_max_helper< T, true >
 
struct  integer_min_helper
 
struct  integer_min_helper< T, false >
 
struct  integer_min_helper< T, true >
 
struct  InterruptLoggerInfo
 
struct  is_comparable_to_nullptr
 
struct  is_dereferenceable
 
struct  is_member_data_pointer
 
struct  is_member_data_pointer< T C::* >
 
struct  is_non_bool_integer
 
struct  is_pointer_like
 
struct  is_pointer_like< fl::unique_ptr< T, Deleter > >
 
struct  is_pointer_like< T * >
 
struct  is_reference
 
struct  is_reference< T & >
 
struct  is_reference< T && >
 
struct  is_swappable
 
struct  is_swappable< T, decltype(void(fl::declval< T & >()=fl::declval< T && >()))>
 
struct  JsonToBoolVisitor
 
struct  JsonToFloatVisitor
 
struct  JsonToIntegerVisitor
 
struct  JsonToStringVisitor
 
struct  JsonToType
 
struct  JsonToType< bool, void >
 
struct  JsonToType< fl::ConstCharPtrWrapper, void >
 
struct  JsonToType< fl::ConstSpanWrapper< T >, void >
 
struct  JsonToType< fl::json, void >
 
struct  JsonToType< fl::string, void >
 
struct  JsonToType< fl::vector< fl::u8 >, void >
 
struct  JsonToType< fl::vector< T >, void >
 
struct  JsonToType< T, typename fl::enable_if< fl::is_floating_point< T >::value >::type >
 
struct  JsonToType< T, typename fl::enable_if< fl::is_integral< T >::value &&!fl::is_same< T, bool >::value >::type >
 
class  KalmanFilterImpl
 
class  LeakyIntegratorImpl
 
struct  LutArray
 
struct  make_shared_tag
 
union  max_align_with_ld
 
union  max_align_without_ld
 
class  MedianFilterImpl
 
class  memorybuf
 
class  MethodBuilder
 
struct  MethodSchema
 
struct  MethodSchema< R(Args...)>
 
struct  MethodSchema< void(Args...)>
 
class  MovingAverageImpl
 
struct  no_op_deleter
 
struct  no_tracking_tag
 
struct  ObjectFLEDLoggerInfo
 
class  OneEuroFilterImpl
 
struct  ParlioLoggerInfo
 Info providers for each logger category Used to supply category name, define name, and enabled status. More...
 
class  posix_filebuf
 
struct  resolve_bus
 Resolve a possibly-Bus::AUTO template argument to the concrete platform default for the given Chipset family. More...
 
struct  resolve_bus< Bus::AUTO, Chipset >
 
class  ResponseAwareInvoker
 Invoker for response-aware RPC methods. More...
 
class  ResponseAwareInvoker< R(Args...)>
 
class  ResponseAwareInvoker< void(Args...)>
 
struct  RmtLoggerInfo
 
struct  RpcEntry
 
class  SavitzkyGolayFilterImpl
 
class  ScaledPixelIteratorBrightness
 Input iterator adapter for PixelIterator yielding brightness values. More...
 
class  ScaledPixelIteratorRGB
 Input iterator adapter for PixelIterator yielding 3-byte pixel data. More...
 
class  ScaledPixelIteratorRGB16
 Input iterator adapter for PixelIterator yielding 16-bit RGB pixel data. More...
 
class  ScaledPixelIteratorRGBW
 Input iterator adapter for PixelIterator yielding 4-byte pixel data. More...
 
class  ScaledPixelIteratorRGBWW
 Input iterator adapter yielding 5-byte RGBWW pixels (issue #2558). More...
 
class  SpectralVarianceImpl
 Multi-channel EMA with per-bin relative deviation measurement. More...
 
struct  SpiLoggerInfo
 
class  TriangularFilterImpl
 
struct  TypedCallableHolder
 
class  TypedInvoker
 
class  TypedInvoker< R(Args...)>
 
class  TypedInvoker< void(Args...)>
 
class  TypedSchemaGenerator
 
struct  TypeSchema
 
struct  TypeSchema< bool, void >
 
struct  TypeSchema< fl::string, void >
 
struct  TypeSchema< T, typename fl::enable_if< fl::is_floating_point< T >::value >::type >
 
struct  TypeSchema< T, typename fl::enable_if< fl::is_integral< T >::value &&!fl::is_same< T, bool >::value >::type >
 
struct  TypeSchema< void, void >
 
struct  TypeTag
 
struct  TypeToJson
 
struct  TypeToJson< fl::json >
 
struct  TypeToJson< fl::string >
 
struct  TypeToJson< fl::vector< fl::u8 > >
 
struct  TypeToJson< fl::vector< T > >
 
struct  TypeToJson< void >
 
struct  use_pointer_syntax
 
class  WeightedMovingAverageImpl
 

Typedefs

template<typename T>
using enable_if_integer_t
 
typedef const void * pgm_p
 

Enumerations

enum class  HexIntWidth : u8 { Width8 = 8 , Width16 = 16 , Width32 = 32 , Width64 = 64 }
 Integer width classification for hex conversion. More...
 
enum class  log_kind : fl::u8 { WARN = 0 , ERROR = 1 , INFO = 2 }
 

Functions

void FL_IRAM async_log_flush_timer_isr (void *user_data)
 
template<typename F>
atan2_full_ (F y, F x) FL_NOEXCEPT
 
template<typename F>
atan_full_ (F u) FL_NOEXCEPT
 
template<typename F>
atan_poly_unit_ (F u) FL_NOEXCEPT
 
template<Bus B>
int bus_register_one () FL_NOEXCEPT
 Helper used by enableDrivers<Bus...>() to expand the parameter pack.
 
template<typename InfoProvider>
void checkLoggerEnabled ()
 Check if logger is enabled and print error once if not.
 
template<typename F>
cos_poly_quarterturn_ (F x) FL_NOEXCEPT
 
template<typename F>
cos_reduce_ (F x) FL_NOEXCEPT
 
constexpr fl::u32 cycles_from_ns (fl::u32 ns, fl::u32 hz) FL_NOEXCEPT
 Convert nanoseconds to CPU cycles.
 
constexpr fl::u32 cycles_from_ns_default (fl::u32 ns) FL_NOEXCEPT
 Compute cycles using default CPU frequency (compile-time)
 
void delay_impl (u32 ms, bool run_async=true) FL_NOEXCEPT
 Internal delay implementation used by the public fl::delay wrapper.
 
template<typename T>
fl::enable_if< fl::is_floating_point< T >::value, T >::type div_by_count (T sum, fl::size count)
 
template<typename T>
fl::enable_if< fl::is_integral< T >::value, T >::type div_by_count (T sum, fl::size count)
 
template<typename T>
fl::enable_if<!fl::is_floating_point< T >::value &&!fl::is_integral< T >::value, T >::type div_by_count (T sum, fl::size count)
 
template<typename T>
fl::enable_if< has_copy_ctor< T >::value, void(*)(void *, constvoid *) FL_NOEXCEPT >::type get_copy_construct_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if<!has_copy_ctor< T >::value, void(*)(void *, constvoid *) FL_NOEXCEPT >::type get_copy_construct_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if< has_default_ctor< T >::value, void(*)(void *) FL_NOEXCEPT >::type get_default_construct_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if<!has_default_ctor< T >::value, void(*)(void *) FL_NOEXCEPT >::type get_default_construct_fn () FL_NOEXCEPT
 
template<size_t Size>
constexpr HexIntWidth get_hex_int_width () FL_NOEXCEPT
 Compile-time integer width determination (default - triggers error)
 
template<>
constexpr HexIntWidth get_hex_int_width< 1 > () FL_NOEXCEPT
 Specialization for 1-byte types (int8_t, uint8_t, char, etc.)
 
template<>
constexpr HexIntWidth get_hex_int_width< 2 > () FL_NOEXCEPT
 Specialization for 2-byte types (int16_t, uint16_t, short, etc.)
 
template<>
constexpr HexIntWidth get_hex_int_width< 4 > () FL_NOEXCEPT
 Specialization for 4-byte types (int32_t, uint32_t, int, etc.)
 
template<>
constexpr HexIntWidth get_hex_int_width< 8 > () FL_NOEXCEPT
 Specialization for 8-byte types (i64, u64, long long, etc.)
 
template<typename T>
fl::enable_if< has_move_ctor< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type get_move_construct_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if<!has_move_ctor< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type get_move_construct_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if< is_swappable< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type get_swap_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if<!is_swappable< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type get_swap_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if< has_move_ctor< T >::value, void(*)(void *, void *, fl::size) FL_NOEXCEPT >::type get_uninitialized_move_n_fn () FL_NOEXCEPT
 
template<typename T>
fl::enable_if<!has_move_ctor< T >::value, void(*)(void *, void *, fl::size) FL_NOEXCEPT >::type get_uninitialized_move_n_fn () FL_NOEXCEPT
 
fl::u32 getWaitSpinBudgetUs () FL_NOEXCEPT
 Get the current tiered-wait spin budget (microseconds).
 
template<typename Iterator, typename Compare>
void heap_sort (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
template<typename Iterator, typename Compare>
void heapify (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
fl::string hex (u64 value, HexIntWidth width, bool is_negative, bool uppercase, bool pad_to_width) FL_NOEXCEPT
 Internal hex conversion function (implementation in charconv.cpp)
 
template<typename IntT>
constexpr bool in_unsigned_range (IntT n, u32 max_u) FL_NOEXCEPT
 
template<typename Iterator, typename Compare>
void insertion_sort (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
template<typename T>
constexpr int integer_digits10_func () FL_NOEXCEPT
 
template<typename T>
constexpr int integer_digits_func () FL_NOEXCEPT
 
void integer_out_of_range_for_fixed_point_type () FL_NOEXCEPT
 
template<typename F>
ldexp_loop_ (F value, int exp) FL_NOEXCEPT
 
FL_NO_INLINE void log_emit (log_kind kind, const char *file, int line, fl::sstream &body) FL_NOEXCEPT
 
template<typename F>
log_natural_ (F value) FL_NOEXCEPT
 
template<typename Iterator, typename T, typename Compare>
Iterator lower_bound_impl (Iterator first, Iterator last, const T &value, Compare comp) FL_NOEXCEPT
 
template<typename Fn, fl::size... Is>
constexpr LutArray< u16, sizeof...(Is)> make_lut_u16 (fl::index_sequence< Is... >) FL_NOEXCEPT
 
template<typename Fn, fl::size... Is>
constexpr LutArray< u8, sizeof...(Is)> make_lut_u8 (fl::index_sequence< Is... >) FL_NOEXCEPT
 
json makeJsonRpcError (int code, const fl::string &message, const json &id)
 
template<typename Iterator, typename Compare>
Iterator median_of_three (Iterator first, Iterator middle, Iterator last, Compare comp) FL_NOEXCEPT
 
template<typename Iterator, typename Compare>
void merge_inplace (Iterator first, Iterator middle, Iterator last, Compare comp) FL_NOEXCEPT
 
template<typename Iterator, typename Compare>
void mergesort_impl (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
void not_null_assert_failed (const char *message)
 
template<typename Iterator, typename Compare>
Iterator partition (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
void printLoggerDisabledError (const char *category_name, const char *define_name)
 Print error message for disabled logger (non-template helper) Called from checkLoggerEnabled template function IMPORTANT: This must NOT be inline - needs external linkage for cross-TU calls.
 
void qsort_impl (char *base, size_t nmemb, size_t size, qsort_compare_fn compar)
 
void qsort_swap (char *a, char *b, size_t size)
 
template<typename Iterator, typename Compare>
void quicksort_impl (Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
 
template<typename Iterator>
void rotate_impl (Iterator first, Iterator middle, Iterator last) FL_NOEXCEPT
 
void setWaitSpinBudgetUs (fl::u32 budget_us) FL_NOEXCEPT
 Set the tiered-wait spin budget (microseconds).
 
template<typename Iterator, typename Compare>
void sift_down (Iterator first, Iterator start, Iterator end, Compare comp) FL_NOEXCEPT
 
template<typename F>
sin_poly_quarterturn_ (F x) FL_NOEXCEPT
 
template<typename F>
sin_reduce_ (F x) FL_NOEXCEPT
 
void * singleton_registry_get (const char *key)
 
void singleton_registry_set (const char *key, void *value)
 
void * slab_allocator_registry_get (fl::size block_size, fl::size slab_size)
 
void slab_allocator_registry_set (fl::size block_size, fl::size slab_size, void *allocator)
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose16_symbol (const u8 l[16], u8 out[16])
 Transpose one symbol of 16 lanes (16 input bytes) into 16 output bytes: 8 pulses × 2 bytes, low byte = lanes 0-7, high byte = lanes 8-15, pulse order 7..0 (out[0] = pulse 7 low).
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose8_symbol (const u8 l[8], u8 out[8])
 Transpose one symbol of 8 lanes (8 input bytes) into 8 output bytes: 8 pulses × 1 byte (bit L = lane L), pulse order 7..0 (out[0] = pulse 7).
 
FASTLED_FORCE_INLINE u32 spreadA (u8 v)
 Pulses 7,6,5,4 of v (byte j = bit (7-j)). Depends only on the high nibble.
 
FASTLED_FORCE_INLINE u32 spreadB (u8 v)
 Pulses 3,2,1,0 of v (byte j = bit (3-j)). Depends only on the low nibble.
 
template<typename F>
sqrt_newton_ (F value) FL_NOEXCEPT
 
template<typename T>
constexpr bool test_encoder (...) FL_NOEXCEPT
 
template<typename T>
constexpr auto test_encoder (int) FL_NOEXCEPT -> decltype(T::ENCODER, true)
 
void to_string (const fl::u16 *bit_data, fl::u32 bit_count, string *dst)
 
template<typename TSrcPalette, typename TDestPalette>
void UpscalePaletteInterpolated (const TSrcPalette &srcpal, TDestPalette &destpal)
 
template<typename TSrcPalette, typename TDestPalette>
void UpscalePaletteRepeat (const TSrcPalette &srcpal, TDestPalette &destpal)
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave3_convert_byte_to_wave3byte (u8 byte_value, const Wave3BitExpansionLut &lut, Wave3Byte *output)
 Helper: Convert byte to Wave3Byte using nibble LUT (internal use only)
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave3_transpose_16 (const Wave3Byte lane_waves[16], u8 output[16 *sizeof(Wave3Byte)])
 Transpose 16 lanes of Wave3Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave3_transpose_2 (const Wave3Byte lane_waves[2], u8 output[2 *sizeof(Wave3Byte)])
 Transpose 2 lanes of Wave3Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave3_transpose_4 (const Wave3Byte lane_waves[4], u8 output[4 *sizeof(Wave3Byte)])
 Transpose 4 lanes of Wave3Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave3_transpose_8 (const Wave3Byte lane_waves[8], u8 output[8 *sizeof(Wave3Byte)])
 Transpose 8 lanes of Wave3Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_convert_byte_to_wave8byte (u8 byte_value, const Wave8BitExpansionLut &lut, Wave8Byte *output)
 Helper: Convert byte to Wave8Byte using nibble LUT (internal use only)
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_expand_byte (u8 byte_value, const Wave8ByteExpansionLut &lut, Wave8Byte *output)
 Byte-indexed expansion (#2526): one indexed 8-byte copy.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16 (const Wave8Byte lane_waves[16], u8 output[16 *sizeof(Wave8Byte)])
 Transpose 16 lanes of Wave8Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16_bf1 (const u8 lanes[16], u8 W0, u8 W1, u8 output[16 *sizeof(Wave8Byte)])
 BF1: chipset-aware direct encode for Wave8 16-lane (#2548 deep-dive).
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x2_pipe2 (const Wave8Byte lane_waves_a[16], const Wave8Byte lane_waves_b[16], u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)])
 Pipe2: transpose 16-lane × 2-byte-positions in one fused call.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x4_bf1_pipe4 (const u8 lanes_a[16], const u8 lanes_b[16], const u8 lanes_c[16], const u8 lanes_d[16], u8 W0, u8 W1, u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)], u8 output_c[16 *sizeof(Wave8Byte)], u8 output_d[16 *sizeof(Wave8Byte)])
 BF1 + pipe4: 4-position software-pipelined BF1 (#2548 deep-dive).
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_16x4_pipe4 (const Wave8Byte lane_waves_a[16], const Wave8Byte lane_waves_b[16], const Wave8Byte lane_waves_c[16], const Wave8Byte lane_waves_d[16], u8 output_a[16 *sizeof(Wave8Byte)], u8 output_b[16 *sizeof(Wave8Byte)], u8 output_c[16 *sizeof(Wave8Byte)], u8 output_d[16 *sizeof(Wave8Byte)])
 Pipe4: transpose 16-lane × 4-byte-positions in one fused call.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_2 (const Wave8Byte lane_waves[2], u8 output[2 *sizeof(Wave8Byte)])
 Transpose 2 lanes of Wave8Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_2_bf1 (const u8 lanes[2], u8 W0, u8 W1, u8 output[2 *sizeof(Wave8Byte)])
 BF1 for 2-lane Wave8.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_4 (const Wave8Byte lane_waves[4], u8 output[4 *sizeof(Wave8Byte)])
 Transpose 4 lanes of Wave8Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_4_bf1 (const u8 lanes[4], u8 W0, u8 W1, u8 output[4 *sizeof(Wave8Byte)])
 BF1 for 4-lane Wave8.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_8 (const Wave8Byte lane_waves[8], u8 output[8 *sizeof(Wave8Byte)])
 Transpose 8 lanes of Wave8Byte data into interleaved format.
 
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void wave8_transpose_8_bf1 (const u8 lanes[8], u8 W0, u8 W1, u8 output[8 *sizeof(Wave8Byte)])
 BF1 for 8-lane Wave8 — same algebraic identity as 16-lane BF1.
 

Variables

constexpr u32 kSpreadNibble [16]
 kSpreadNibble[n] places the 4 bits of nibble n at bit 0 of 4 separate bytes: byte0 = bit3(n), byte1 = bit2(n), byte2 = bit1(n), byte3 = bit0(n).
 
constexpr u8 kTranspose2_4_LUT [4]
 
constexpr u8 kTranspose4_16_LUT [16]
 

◆ fl::detail::integer_max_helper

struct fl::detail::integer_max_helper
+ Inheritance diagram for fl::detail::integer_max_helper< T, IsSigned >:

◆ fl::detail::integer_min_helper

struct fl::detail::integer_min_helper
+ Inheritance diagram for fl::detail::integer_min_helper< T, IsSigned >:

◆ fl::detail::LutArray

struct fl::detail::LutArray
+ Inheritance diagram for fl::detail::LutArray< T, N >:
Class Members
T values[N]

◆ fl::detail::make_shared_tag

struct fl::detail::make_shared_tag

◆ fl::detail::max_align_with_ld

union fl::detail::max_align_with_ld
Class Members
long double ld
long long ll
void * p

◆ fl::detail::max_align_without_ld

union fl::detail::max_align_without_ld
Class Members
double d
long long ll
void * p

◆ fl::detail::MethodSchema

struct fl::detail::MethodSchema
+ Inheritance diagram for fl::detail::MethodSchema< Sig >:

◆ fl::detail::no_tracking_tag

struct fl::detail::no_tracking_tag

◆ fl::detail::ResponseAwareInvoker

class fl::detail::ResponseAwareInvoker
+ Inheritance diagram for fl::detail::ResponseAwareInvoker< Sig >:

◆ fl::detail::RpcEntry

struct fl::detail::RpcEntry
+ Collaboration diagram for fl::detail::RpcEntry:
Class Members
string mDescription
shared_ptr< ErasedInvoker > mInvoker
bool mIsResponseAware = false
RpcMode mMode = fl::RpcMode::SYNC
function< void(ResponseSend &, const json &)> mResponseAwareFn
shared_ptr< ErasedSchemaGenerator > mSchemaGenerator
vector< string > mTags
shared_ptr< CallableHolderBase > mTypedCallable
const void * mTypeTag = nullptr

◆ fl::detail::TypedInvoker

class fl::detail::TypedInvoker
+ Inheritance diagram for fl::detail::TypedInvoker< Sig >:

Typedef Documentation

◆ enable_if_integer_t

template<typename T>
using fl::detail::enable_if_integer_t
Initial value:

Definition at line 28 of file traits.h.

◆ pgm_p

typedef const void* fl::detail::pgm_p

Definition at line 114 of file cstring.h.

Enumeration Type Documentation

◆ HexIntWidth

enum class fl::detail::HexIntWidth : u8
strong

Integer width classification for hex conversion.

Enumerator
Width8 
Width16 
Width32 
Width64 

Definition at line 42 of file charconv.h.

42 : u8 {
43 Width8 = 8,
44 Width16 = 16,
45 Width32 = 32,
46 Width64 = 64
47};
unsigned char u8
Definition stdint.h:131

◆ log_kind

enum class fl::detail::log_kind : fl::u8
strong
Enumerator
WARN 
ERROR 
INFO 

Definition at line 173 of file log.h.

173 : fl::u8 {
174 WARN = 0,
175 ERROR = 1,
176 INFO = 2,
177};
@ ERROR
Definition ServerReal.h:44
unsigned char u8
Definition stdint.h:131

Function Documentation

◆ async_log_flush_timer_isr()

void FL_IRAM fl::detail::async_log_flush_timer_isr ( void * user_data)

Definition at line 44 of file async_logger.cpp.hpp.

44 {
45 BackgroundFlushState* state = static_cast<BackgroundFlushState*>(user_data);
46 state->mNeedsFlush = true;
47 // Debug: Toggle a counter to verify ISR is firing (visible in debugger)
48 static volatile fl::u32 isr_fire_count = 0;
49 isr_fire_count = isr_fire_count + 1;
50 }
TestState state

References FL_IRAM, and state.

Referenced by fl::AsyncLogger::enableBackgroundFlush().

+ Here is the caller graph for this function:

◆ atan2_full_()

template<typename F>
F fl::detail::atan2_full_ ( F y,
F x )
inline

Definition at line 479 of file math.cpp.hpp.

479 {
480 const F kPi = F(3.14159265358979323846);
481 const F kPiHalf = F(1.57079632679489661923);
482 // x == 0 special case: angle is ±π/2 (sign of y), or 0 when both are 0.
483 if (x == F(0)) {
484 if (y > F(0)) return kPiHalf;
485 if (y < F(0)) return -kPiHalf;
486 return F(0);
487 }
488 F a = atan_full_(y / x);
489 if (x < F(0)) {
490 a += (y >= F(0)) ? kPi : -kPi;
491 }
492 return a;
493}
F atan_full_(F u) FL_NOEXCEPT
Definition math.cpp.hpp:467

References atan_full_(), FL_NOEXCEPT, fl::x, and fl::y.

Referenced by fl::atan2_impl_double(), and fl::atan2_impl_float().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atan_full_()

template<typename F>
F fl::detail::atan_full_ ( F u)
inline

Definition at line 467 of file math.cpp.hpp.

467 {
468 const F kPiHalf = F(1.57079632679489661923);
469 // Reduce to |u| <= 1 via the reciprocal identity.
470 if (u > F(1)) {
471 return kPiHalf - atan_poly_unit_(F(1) / u);
472 } else if (u < F(-1)) {
473 return -kPiHalf - atan_poly_unit_(F(1) / u);
474 }
475 return atan_poly_unit_(u);
476}
F atan_poly_unit_(F u) FL_NOEXCEPT
Definition math.cpp.hpp:454

References atan_poly_unit_(), and FL_NOEXCEPT.

Referenced by fl::asin_impl_double(), fl::asin_impl_float(), atan2_full_(), fl::atan_impl_double(), and fl::atan_impl_float().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atan_poly_unit_()

template<typename F>
F fl::detail::atan_poly_unit_ ( F u)
inline

Definition at line 454 of file math.cpp.hpp.

454 {
455 // Polynomial approximation of atan on [-1, 1].
456 // Coefficients from Padé-style minimax fit; max abs error ~1.5e-3.
457 const F u2 = u * u;
458 return u * (F(0.99997726) +
459 u2 * (F(-0.33262347) +
460 u2 * (F(0.19354346) +
461 u2 * (F(-0.11643287) +
462 u2 * (F(0.05265332) +
463 u2 * F(-0.01172120))))));
464}

References FL_NOEXCEPT.

Referenced by atan_full_().

+ Here is the caller graph for this function:

◆ bus_register_one()

template<Bus B>
int fl::detail::bus_register_one ( )
inline

Helper used by enableDrivers<Bus...>() to expand the parameter pack.

Each call ODR-uses BusTraits<B>::registerWithManager(), which lazily constructs the driver singleton AND registers it with ChannelManager.

Definition at line 54 of file bus_traits.h.

54 {
56 return 0;
57}
Primary template — intentionally undefined.
Definition bus_traits.h:30

References FL_NOEXCEPT.

Referenced by fl::enableDrivers().

+ Here is the caller graph for this function:

◆ checkLoggerEnabled()

template<typename InfoProvider>
void fl::detail::checkLoggerEnabled ( )
inline

Check if logger is enabled and print error once if not.

Template Parameters
InfoProviderType providing category name, define name, and enabled status

Definition at line 80 of file async_logger.h.

80 {
81 if (!InfoProvider::isEnabled()) {
82 static bool error_printed = false;
83 if (!error_printed) {
84 error_printed = true;
85 printLoggerDisabledError(InfoProvider::categoryName(), InfoProvider::defineName());
86 }
87 }
88 }
void printLoggerDisabledError(const char *category_name, const char *define_name)
Print error message for disabled logger (non-template helper) Called from checkLoggerEnabled template...

References checkLoggerEnabled(), and printLoggerDisabledError().

Referenced by checkLoggerEnabled(), and fl::get_async_logger_by_index().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cos_poly_quarterturn_()

template<typename F>
F fl::detail::cos_poly_quarterturn_ ( F x)
inline

Definition at line 177 of file math.cpp.hpp.

177 {
178 // cos(x) ≈ 1 - x²/2 + x⁴/24 - x⁶/720
179 const F x2 = x * x;
180 return F(1) - x2 * (F(0.5) - x2 * (F(1.0 / 24.0) - x2 * F(1.0 / 720.0)));
181}

References FL_NOEXCEPT, and fl::x.

◆ cos_reduce_()

template<typename F>
F fl::detail::cos_reduce_ ( F x)
inline

Definition at line 202 of file math.cpp.hpp.

202 {
203 // cos(x) = sin(π/2 - x)
204 const F kPiHalf = F(1.57079632679489661923);
205 return sin_reduce_(kPiHalf - x);
206}
F sin_reduce_(F x) FL_NOEXCEPT
Definition math.cpp.hpp:184

References FL_NOEXCEPT, sin_reduce_(), and fl::x.

Referenced by fl::cos_impl_double(), fl::cos_impl_float(), fl::tan_impl_double(), and fl::tan_impl_float().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cycles_from_ns()

fl::u32 fl::detail::cycles_from_ns ( fl::u32 ns,
fl::u32 hz )
constexpr

Convert nanoseconds to CPU cycles.

Parameters
nsNumber of nanoseconds
hzCPU frequency in Hz
Returns
Number of cycles (rounded up)

Definition at line 29 of file delay.h.

29 {
30 // Round up: cycles = ceil(ns * hz / 1e9)
31 // Using: (ns * hz + 999'999'999) / 1'000'000'000
32 return ((fl::u64)ns * (fl::u64)hz + 999999999UL) / 1000000000UL;
33}
fl::u64 u64
Definition s16x16x4.h:221

References FL_NOEXCEPT.

Referenced by cycles_from_ns_default().

+ Here is the caller graph for this function:

◆ cycles_from_ns_default()

fl::u32 fl::detail::cycles_from_ns_default ( fl::u32 ns)
constexpr

Compute cycles using default CPU frequency (compile-time)

Parameters
nsNumber of nanoseconds
Returns
Number of cycles using GET_CPU_FREQUENCY()

Definition at line 38 of file delay.h.

38 {
39 return cycles_from_ns(ns, GET_CPU_FREQUENCY());
40}
constexpr fl::u32 cycles_from_ns(fl::u32 ns, fl::u32 hz) FL_NOEXCEPT
Convert nanoseconds to CPU cycles.
Definition delay.h:29

References cycles_from_ns(), and FL_NOEXCEPT.

+ Here is the call graph for this function:

◆ delay_impl()

void fl::detail::delay_impl ( u32 ms,
bool run_async = true )

Internal delay implementation used by the public fl::delay wrapper.

Parameters
msMilliseconds to delay
run_asyncIf true, pump async tasks during delay (only on platforms with SKETCH_HAS_LARGE_MEMORY==1)

Definition at line 177 of file delay.cpp.hpp.

177 {
178#if SKETCH_HAS_LARGE_MEMORY
179 // Check if delay override is active (for fast testing with stub platform)
180 // When override is active, skip async pumping and use platform delay directly
181#if defined(FASTLED_STUB_IMPL) && (!defined(ARDUINO) || defined(FASTLED_USE_STUB_ARDUINO))
182 if (isDelayOverrideActive()) {
183 fl::platforms::delay(ms); // Use platform override directly
184 return;
185 }
186#endif
187
188 if (run_async && ms > 0) {
189 task::run(ms * 1000);
190 } else {
191 fl::platforms::delay(ms); // Use platform layer for raw delay
192 }
193#else
194 (void)run_async; // Suppress unused parameter warning
195 fl::platforms::delay(ms); // Use platform layer for raw delay
196#endif
197}
void run(fl::u32 microseconds, ExecFlags flags)
Run selected task subsystems.

References FL_NOEXCEPT, and fl::task::run().

Referenced by fl::delay(), fl::delayMillis(), and fl::delayMs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ div_by_count() [1/3]

template<typename T>
fl::enable_if< fl::is_floating_point< T >::value, T >::type fl::detail::div_by_count ( T sum,
fl::size count )
inline

Definition at line 11 of file div_by_count.h.

11{ return sum / static_cast<T>(count); }

Referenced by fl::detail::SavitzkyGolayFilterImpl< T, N >::recompute(), fl::detail::AlphaTrimmedMeanImpl< T, N >::update(), fl::detail::AlphaTrimmedMeanImpl< T, N >::update(), and fl::detail::HampelFilterImpl< T, N >::update().

+ Here is the caller graph for this function:

◆ div_by_count() [2/3]

template<typename T>
fl::enable_if< fl::is_integral< T >::value, T >::type fl::detail::div_by_count ( T sum,
fl::size count )
inline

Definition at line 15 of file div_by_count.h.

15{ return sum / static_cast<T>(count); }

◆ div_by_count() [3/3]

template<typename T>
fl::enable_if<!fl::is_floating_point< T >::value &&!fl::is_integral< T >::value, T >::type fl::detail::div_by_count ( T sum,
fl::size count )
inline

Definition at line 20 of file div_by_count.h.

20{ return sum / T(static_cast<float>(count)); }

◆ get_copy_construct_fn() [1/2]

template<typename T>
fl::enable_if< has_copy_ctor< T >::value, void(*)(void *, constvoid *) FL_NOEXCEPT >::type fl::detail::get_copy_construct_fn ( )

Definition at line 223 of file basic_vector.h.

223 {
224 return [](void* dst, const void* src) FL_NOEXCEPT {
225 new (dst) T(*static_cast<const T*>(src));
226 };
227}
#define FL_NOEXCEPT

References FL_NOEXCEPT.

Referenced by fl::vector_element_ops_for().

+ Here is the caller graph for this function:

◆ get_copy_construct_fn() [2/2]

template<typename T>
fl::enable_if<!has_copy_ctor< T >::value, void(*)(void *, constvoid *) FL_NOEXCEPT >::type fl::detail::get_copy_construct_fn ( )

Definition at line 232 of file basic_vector.h.

232 {
233 return nullptr;
234}

References FL_NOEXCEPT.

◆ get_default_construct_fn() [1/2]

template<typename T>
fl::enable_if< has_default_ctor< T >::value, void(*)(void *) FL_NOEXCEPT >::type fl::detail::get_default_construct_fn ( )

Definition at line 209 of file basic_vector.h.

209 {
210 return [](void* ptr) FL_NOEXCEPT { new (ptr) T(); };
211}

References FL_NOEXCEPT.

Referenced by fl::vector_element_ops_for().

+ Here is the caller graph for this function:

◆ get_default_construct_fn() [2/2]

template<typename T>
fl::enable_if<!has_default_ctor< T >::value, void(*)(void *) FL_NOEXCEPT >::type fl::detail::get_default_construct_fn ( )

Definition at line 216 of file basic_vector.h.

216 {
217 return nullptr;
218}

References FL_NOEXCEPT.

◆ get_hex_int_width()

template<size_t Size>
HexIntWidth fl::detail::get_hex_int_width ( )
constexpr

Compile-time integer width determination (default - triggers error)

Definition at line 60 of file charconv.h.

60 {
61 FL_STATIC_ASSERT(Size == 0, "Unsupported type size for hex conversion");
62 return HexIntWidth::Width8; // Unreachable, but needed for compilation
63}
#define FL_STATIC_ASSERT(...)

References FL_NOEXCEPT, FL_STATIC_ASSERT, get_hex_int_width(), and Width8.

Referenced by get_hex_int_width(), get_hex_int_width< 1 >(), get_hex_int_width< 2 >(), get_hex_int_width< 4 >(), get_hex_int_width< 8 >(), and fl::to_hex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_hex_int_width< 1 >()

template<>
HexIntWidth fl::detail::get_hex_int_width< 1 > ( )
constexpr

Specialization for 1-byte types (int8_t, uint8_t, char, etc.)

Definition at line 67 of file charconv.h.

67 {
69}

References FL_NOEXCEPT, get_hex_int_width(), and Width8.

+ Here is the call graph for this function:

◆ get_hex_int_width< 2 >()

template<>
HexIntWidth fl::detail::get_hex_int_width< 2 > ( )
constexpr

Specialization for 2-byte types (int16_t, uint16_t, short, etc.)

Definition at line 73 of file charconv.h.

73 {
75}

References FL_NOEXCEPT, get_hex_int_width(), and Width16.

+ Here is the call graph for this function:

◆ get_hex_int_width< 4 >()

template<>
HexIntWidth fl::detail::get_hex_int_width< 4 > ( )
constexpr

Specialization for 4-byte types (int32_t, uint32_t, int, etc.)

Definition at line 79 of file charconv.h.

79 {
81}

References FL_NOEXCEPT, get_hex_int_width(), and Width32.

+ Here is the call graph for this function:

◆ get_hex_int_width< 8 >()

template<>
HexIntWidth fl::detail::get_hex_int_width< 8 > ( )
constexpr

Specialization for 8-byte types (i64, u64, long long, etc.)

Definition at line 85 of file charconv.h.

85 {
87}

References FL_NOEXCEPT, get_hex_int_width(), and Width64.

+ Here is the call graph for this function:

◆ get_move_construct_fn() [1/2]

template<typename T>
fl::enable_if< has_move_ctor< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type fl::detail::get_move_construct_fn ( )

Definition at line 255 of file basic_vector.h.

255 {
256 return [](void* dst, void* src) FL_NOEXCEPT {
257 new (dst) T(static_cast<T&&>(*static_cast<T*>(src)));
258 };
259}

References FL_NOEXCEPT.

Referenced by fl::vector_element_ops_for().

+ Here is the caller graph for this function:

◆ get_move_construct_fn() [2/2]

template<typename T>
fl::enable_if<!has_move_ctor< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type fl::detail::get_move_construct_fn ( )

Definition at line 263 of file basic_vector.h.

263 {
264 return nullptr;
265}

References FL_NOEXCEPT.

◆ get_swap_fn() [1/2]

template<typename T>
fl::enable_if< is_swappable< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type fl::detail::get_swap_fn ( )

Definition at line 270 of file basic_vector.h.

270 {
271 return [](void* a, void* b) FL_NOEXCEPT {
272 T& ta = *static_cast<T*>(a);
273 T& tb = *static_cast<T*>(b);
274 T tmp(static_cast<T&&>(ta));
275 ta = static_cast<T&&>(tb);
276 tb = static_cast<T&&>(tmp);
277 };
278}

References FL_NOEXCEPT.

Referenced by fl::vector_element_ops_for().

+ Here is the caller graph for this function:

◆ get_swap_fn() [2/2]

template<typename T>
fl::enable_if<!is_swappable< T >::value, void(*)(void *, void *) FL_NOEXCEPT >::type fl::detail::get_swap_fn ( )

Definition at line 282 of file basic_vector.h.

282 {
283 return nullptr;
284}

References FL_NOEXCEPT.

◆ get_uninitialized_move_n_fn() [1/2]

template<typename T>
fl::enable_if< has_move_ctor< T >::value, void(*)(void *, void *, fl::size) FL_NOEXCEPT >::type fl::detail::get_uninitialized_move_n_fn ( )

Definition at line 289 of file basic_vector.h.

289 {
290 return [](void* dst, void* src, fl::size count) FL_NOEXCEPT {
291 T* d = static_cast<T*>(dst);
292 T* s = static_cast<T*>(src);
293 for (fl::size i = 0; i < count; ++i) {
294 new (&d[i]) T(static_cast<T&&>(s[i]));
295 }
296 };
297}

References FL_NOEXCEPT.

Referenced by fl::vector_element_ops_for().

+ Here is the caller graph for this function:

◆ get_uninitialized_move_n_fn() [2/2]

template<typename T>
fl::enable_if<!has_move_ctor< T >::value, void(*)(void *, void *, fl::size) FL_NOEXCEPT >::type fl::detail::get_uninitialized_move_n_fn ( )

Definition at line 301 of file basic_vector.h.

301 {
302 return nullptr;
303}

References FL_NOEXCEPT.

◆ getWaitSpinBudgetUs()

fl::u32 fl::detail::getWaitSpinBudgetUs ( )

Get the current tiered-wait spin budget (microseconds).

Definition at line 29 of file wait_spin_budget.cpp.hpp.

29 {
30 return sWaitSpinBudgetUs.load();
31}

References FL_NOEXCEPT.

Referenced by CFastLED::_getWaitSpinBudgetUs(), fl::ChannelManager::waitForCondition(), and fl::IChannelDriver::waitForCondition().

+ Here is the caller graph for this function:

◆ heap_sort()

template<typename Iterator, typename Compare>
void fl::detail::heap_sort ( Iterator first,
Iterator last,
Compare comp )

Definition at line 398 of file algorithm.h.

398 {
399 heapify(first, last, comp);
400
401 Iterator end = last - 1;
402 while (end > first) {
403 swap(*end, *first);
404 sift_down(first, first, end - 1, comp);
405 --end;
406 }
407}
void heapify(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:385
void sift_down(Iterator first, Iterator start, Iterator end, Compare comp) FL_NOEXCEPT
Definition algorithm.h:360
constexpr T * end(T(&array)[N]) FL_NOEXCEPT
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NOEXCEPT
Definition array.h:209

References fl::end(), FL_NOEXCEPT, heapify(), sift_down(), and fl::swap().

+ Here is the call graph for this function:

◆ heapify()

template<typename Iterator, typename Compare>
void fl::detail::heapify ( Iterator first,
Iterator last,
Compare comp )

Definition at line 385 of file algorithm.h.

385 {
386 Iterator start = first + (last - first - 2) / 2;
387
388 while (true) {
389 sift_down(first, start, last - 1, comp);
390 if (start == first) {
391 break;
392 }
393 --start;
394 }
395}

References FL_NOEXCEPT, and sift_down().

Referenced by heap_sort().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hex()

fl::string fl::detail::hex ( u64 value,
HexIntWidth width,
bool is_negative,
bool uppercase,
bool pad_to_width )

Internal hex conversion function (implementation in charconv.cpp)

Parameters
valueThe unsigned 64-bit value to convert
widthThe bit width classification of the original type
is_negativeWhether the original value was negative (for signed types)
uppercaseIf true, use uppercase hex digits (A-F), otherwise lowercase (a-f)
pad_to_widthIf true, pad with leading zeros to full type width
Returns
Hexadecimal string representation

Definition at line 12 of file charconv.cpp.hpp.

12 {
13 // Determine target width in hex characters based on integer bit width
14 size_t target_width = 0;
15 switch (width) {
16 case HexIntWidth::Width8: target_width = 2; break; // 8 bits = 2 hex chars
17 case HexIntWidth::Width16: target_width = 4; break; // 16 bits = 4 hex chars
18 case HexIntWidth::Width32: target_width = 8; break; // 32 bits = 8 hex chars
19 case HexIntWidth::Width64: target_width = 16; break; // 64 bits = 16 hex chars
20 }
21
23 const char* digits = uppercase ? "0123456789ABCDEF" : "0123456789abcdef";
24
25 // Convert value to hex string (minimal representation)
26 u64 temp_value = value;
27 if (temp_value == 0) {
28 // Special case: zero should be "0" not empty string
29 result = fl::string("0");
30 } else {
31 while (temp_value > 0) {
32 char ch = digits[temp_value % 16];
33 // Convert char to string since fl::string::append treats char as number
34 char temp_ch_str[2] = {ch, '\0'};
35 fl::string digit_str(temp_ch_str);
36 // Use += since + operator is not defined for fl::string
37 fl::string temp = digit_str;
38 temp += result;
39 result = temp;
40 temp_value /= 16;
41 }
42 }
43
44 // Pad with leading zeros to target width (only if padding is requested)
45 if (pad_to_width) {
46 while (result.size() < target_width) {
47 fl::string zero_str("0");
48 zero_str += result;
49 result = zero_str;
50 }
51 }
52
53 // Add negative sign if needed
54 if (is_negative) {
55 fl::string minus_str("-");
56 minus_str += result;
57 result = minus_str;
58 }
59
60 return result;
61}
constexpr int type_rank< T >::value
u8 width
Definition blur.h:186
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
constexpr int numeric_limits< char >::digits

References fl::numeric_limits< char >::digits, fl::type_rank< T >::value, fl::width, Width16, Width32, Width64, and Width8.

Referenced by fl::to_hex().

+ Here is the caller graph for this function:

◆ in_unsigned_range()

template<typename IntT>
bool fl::detail::in_unsigned_range ( IntT n,
u32 max_u )
constexpr

Definition at line 39 of file traits.h.

39 {
40 return static_cast<i32>(fl::is_signed<IntT>::value ? (n >= IntT(0)) : 1) &&
41 static_cast<u32>(n) <= max_u;
42}

References FL_NOEXCEPT, and fl::fl::is_signed< T >::value.

Referenced by fl::detail::int_to_fixed< IntBits, FracBits, false >::from_unsigned(), and fl::detail::int_to_fixed< IntBits, FracBits, true >::from_unsigned().

+ Here is the caller graph for this function:

◆ insertion_sort()

template<typename Iterator, typename Compare>
void fl::detail::insertion_sort ( Iterator first,
Iterator last,
Compare comp )

Definition at line 298 of file algorithm.h.

298 {
299 if (first == last) return;
300
301 for (Iterator i = first + 1; i != last; ++i) {
302 auto value = fl::move(*i);
303 Iterator j = i;
304
305 while (j != first && comp(value, *(j - 1))) {
306 *j = fl::move(*(j - 1));
307 --j;
308 }
309
310 *j = fl::move(value);
311 }
312}
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28

References FL_NOEXCEPT, fl::fl::move(), and fl::type_rank< T >::value.

Referenced by mergesort_impl(), quicksort_impl(), and fl::sort_small().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ integer_digits10_func()

template<typename T>
int fl::detail::integer_digits10_func ( )
constexpr

Definition at line 30 of file limits.h.

30 {
31 return sizeof(T) == 1 ? 2 :
32 sizeof(T) == 2 ? 4 :
33 sizeof(T) == 4 ? 9 :
34 sizeof(T) == 8 ? 19 : 0;
35 }

References FL_NOEXCEPT.

◆ integer_digits_func()

template<typename T>
int fl::detail::integer_digits_func ( )
constexpr

Definition at line 17 of file limits.h.

17 {
18 return (sizeof(T) * 8) - (T(-1) < T(0) ? 1 : 0);
19 }

References FL_NOEXCEPT.

◆ integer_out_of_range_for_fixed_point_type()

void fl::detail::integer_out_of_range_for_fixed_point_type ( )
inline

Definition at line 33 of file traits.h.

33{}

References FL_NOEXCEPT.

Referenced by fl::detail::int_to_fixed< IntBits, FracBits, false >::from_signed(), fl::detail::int_to_fixed< IntBits, FracBits, true >::from_signed(), fl::detail::int_to_fixed< IntBits, FracBits, false >::from_unsigned(), and fl::detail::int_to_fixed< IntBits, FracBits, true >::from_unsigned().

+ Here is the caller graph for this function:

◆ ldexp_loop_()

template<typename F>
F fl::detail::ldexp_loop_ ( F value,
int exp )
inline

Definition at line 623 of file math.cpp.hpp.

623 {
624 if (value == F(0)) return value;
625 if (exp == 0) return value;
626 if (exp > 0) {
627 // Cap to avoid pathological loops; saturate to ±inf-ish via overflow
628 // (these magnitudes are well outside the IEEE 754 finite range, and
629 // returning a saturated value matches libm's behavior of producing
630 // ±HUGE_VAL on overflow).
631 if (exp > 1024) exp = 1024;
632 while (exp >= 30) { value *= F(1073741824); exp -= 30; } // 2^30
633 while (exp > 0) { value *= F(2); --exp; }
634 return value;
635 }
636 // exp < 0
637 int neg = -exp;
638 if (neg > 1024) neg = 1024;
639 while (neg >= 30) { value *= F(1.0 / 1073741824.0); neg -= 30; }
640 while (neg > 0) { value *= F(0.5); --neg; }
641 return value;
642}
enable_if< is_fixed_point< T >::value, T >::type exp(T x) FL_NOEXCEPT

References fl::exp(), FL_NOEXCEPT, and fl::type_rank< T >::value.

Referenced by fl::ldexp_impl_double(), and fl::ldexp_impl_float().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_emit()

void fl::detail::log_emit ( log_kind kind,
const char * file,
int line,
fl::sstream & body )

Definition at line 31 of file log.cpp.hpp.

31 {
32 const char* tag;
33 switch (kind) {
34 case log_kind::WARN: tag = "): WARN: "; break;
35 case log_kind::ERROR: tag = "): ERROR: "; break;
36 case log_kind::INFO:
37 default: tag = "): INFO: "; break;
38 }
39 // Snapshot the user-supplied payload (the only thing `body`
40 // contains at entry — the macro fed it only `<< X`).
41 fl::string user_payload(body.str());
42 // Reset body's buffer and rebuild prefix-then-payload INTO body.
43 // body is in the caller's frame; the c_str() pointer we hand to
44 // println below lives until the end of the FL_WARN expression.
45 body.clear();
46 body << file << "(" << line << tag << user_payload.c_str();
47 fl::println(body.c_str());
48}
string str() const FL_NOEXCEPT
Definition strstream.h:43
void clear() FL_NOEXCEPT
Definition strstream.h:358
const char * c_str() const FL_NOEXCEPT
Definition strstream.h:44
void println(const char *str) FL_NOEXCEPT

References fl::basic_string::c_str(), ERROR, FL_NO_INLINE, FL_NOEXCEPT, INFO, fl::println(), and WARN.

+ Here is the call graph for this function:

◆ log_natural_()

template<typename F>
F fl::detail::log_natural_ ( F value)
inline

Definition at line 214 of file math.cpp.hpp.

214 {
215 if (value <= F(0)) return F(-1e30); // -inf surrogate
216 int e = 0;
217 while (value >= F(2)) { value *= F(0.5); ++e; }
218 while (value < F(1)) { value *= F(2); --e; }
219 // value ∈ [1, 2); evaluate log(value) via Taylor around 1: let u = value - 1.
220 // log(1+u) = u - u²/2 + u³/3 - u⁴/4 + ...
221 // Use enough terms for ~5-decimal accuracy on [0, 1].
222 const F u = value - F(1);
223 const F u2 = u * u;
224 const F u3 = u2 * u;
225 const F u4 = u2 * u2;
226 const F u5 = u4 * u;
227 const F u6 = u4 * u2;
228 const F u7 = u6 * u;
229 F log_m = u - u2 * F(0.5) + u3 * F(1.0 / 3.0) - u4 * F(0.25)
230 + u5 * F(0.2) - u6 * F(1.0 / 6.0) + u7 * F(1.0 / 7.0);
231 const F kLn2 = F(0.69314718055994530942);
232 return log_m + F(e) * kLn2;
233}

References FL_NOEXCEPT, and fl::type_rank< T >::value.

Referenced by fl::log10_impl_double(), fl::log10_impl_float(), fl::log_impl_double(), fl::log_impl_float(), fl::pow_impl_double(), and fl::pow_impl_float().

+ Here is the caller graph for this function:

◆ lower_bound_impl()

template<typename Iterator, typename T, typename Compare>
Iterator fl::detail::lower_bound_impl ( Iterator first,
Iterator last,
const T & value,
Compare comp )

Definition at line 442 of file algorithm.h.

442 {
443 auto count = last - first;
444 while (count > 0) {
445 auto step = count / 2;
446 Iterator it = first + step;
447 if (comp(*it, value)) {
448 first = ++it;
449 count -= step + 1;
450 } else {
451 count = step;
452 }
453 }
454 return first;
455}
constexpr enable_if< is_fixed_point< T >::value, T >::type step(T edge, T x) FL_NOEXCEPT

References FL_NOEXCEPT, fl::step(), and fl::type_rank< T >::value.

Referenced by fl::lower_bound(), fl::lower_bound(), and merge_inplace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_lut_u16()

template<typename Fn, fl::size... Is>
LutArray< u16, sizeof...(Is)> fl::detail::make_lut_u16 ( fl::index_sequence< Is... > )
constexpr

Definition at line 241 of file gamma_lut.h.

241 {
242 return {{ Fn()(static_cast<u8>(Is))... }};
243}

References FL_NOEXCEPT.

◆ make_lut_u8()

template<typename Fn, fl::size... Is>
LutArray< u8, sizeof...(Is)> fl::detail::make_lut_u8 ( fl::index_sequence< Is... > )
constexpr

Definition at line 235 of file gamma_lut.h.

235 {
236 return {{ Fn()(static_cast<u8>(Is))... }};
237}

References FL_NOEXCEPT.

◆ makeJsonRpcError()

json fl::detail::makeJsonRpcError ( int code,
const fl::string & message,
const json & id )
inline

Definition at line 61 of file rpc_registry.h.

61 {
62 json response = json::object();
63 response.set("jsonrpc", "2.0");
64
65 json error = json::object();
66 error.set("code", code);
67 error.set("message", message);
68 response.set("error", error);
69
70 if (id.has_value()) {
71 response.set("id", id);
72 }
73
74 return response;
75}
void set(const fl::string &key, const json &value) FL_NOEXCEPT
Definition json.h:701
static json object() FL_NOEXCEPT
Definition json.h:692

References fl::json::object(), and fl::json::set().

Referenced by fl::Rpc::handle().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ median_of_three()

template<typename Iterator, typename Compare>
Iterator fl::detail::median_of_three ( Iterator first,
Iterator middle,
Iterator last,
Compare comp )

Definition at line 316 of file algorithm.h.

316 {
317 if (comp(*middle, *first)) {
318 if (comp(*last, *middle)) {
319 return middle;
320 } else if (comp(*last, *first)) {
321 return last;
322 } else {
323 return first;
324 }
325 } else {
326 if (comp(*last, *first)) {
327 return first;
328 } else if (comp(*last, *middle)) {
329 return last;
330 } else {
331 return middle;
332 }
333 }
334}

References FL_NOEXCEPT.

Referenced by partition().

+ Here is the caller graph for this function:

◆ merge_inplace()

template<typename Iterator, typename Compare>
void fl::detail::merge_inplace ( Iterator first,
Iterator middle,
Iterator last,
Compare comp )

Definition at line 459 of file algorithm.h.

459 {
460 // If one of the ranges is empty, nothing to merge
461 if (first == middle || middle == last) {
462 return;
463 }
464
465 // If arrays are small enough, use insertion-based merge
466 auto left_size = middle - first;
467 auto right_size = last - middle;
468 if (left_size + right_size <= 32) {
469 // Simple insertion-based merge for small arrays
470 Iterator left = first;
471 Iterator right = middle;
472
473 while (left < middle && right < last) {
474 if (!comp(*right, *left)) {
475 // left element is in correct position
476 ++left;
477 } else {
478 // right element needs to be inserted into left part
479 auto value = fl::move(*right);
480 Iterator shift_end = right;
481 Iterator shift_start = left;
482
483 // Shift elements to make room
484 while (shift_end > shift_start) {
485 *shift_end = fl::move(*(shift_end - 1));
486 --shift_end;
487 }
488
489 *left = fl::move(value);
490 ++left;
491 ++middle; // middle has shifted right
492 ++right;
493 }
494 }
495 return;
496 }
497
498 // For larger arrays, use rotation-based merge
499 if (left_size == 0 || right_size == 0) {
500 return;
501 }
502
503 if (left_size == 1) {
504 // Find insertion point for the single left element in right array
505 Iterator pos = lower_bound_impl(middle, last, *first, comp);
506 rotate_impl(first, middle, pos);
507 return;
508 }
509
510 if (right_size == 1) {
511 // Find insertion point for the single right element in left array
512 Iterator pos = lower_bound_impl(first, middle, *(last - 1), comp);
513 rotate_impl(pos, middle, last);
514 return;
515 }
516
517 // Divide both arrays and recursively merge
518 Iterator left_mid = first + left_size / 2;
519 Iterator right_mid = lower_bound_impl(middle, last, *left_mid, comp);
520
521 // Rotate to bring the two middle parts together
522 rotate_impl(left_mid, middle, right_mid);
523
524 // Update middle position
525 Iterator new_middle = left_mid + (right_mid - middle);
526
527 // Recursively merge the two parts
528 merge_inplace(first, left_mid, new_middle, comp);
529 merge_inplace(new_middle, right_mid, last, comp);
530}
uint8_t pos
Definition Blur.ino:11
void rotate_impl(Iterator first, Iterator middle, Iterator last) FL_NOEXCEPT
Definition algorithm.h:424
void merge_inplace(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:459
Iterator lower_bound_impl(Iterator first, Iterator last, const T &value, Compare comp) FL_NOEXCEPT
Definition algorithm.h:442

References FL_NOEXCEPT, lower_bound_impl(), merge_inplace(), fl::fl::move(), pos, rotate_impl(), and fl::type_rank< T >::value.

Referenced by merge_inplace(), and mergesort_impl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mergesort_impl()

template<typename Iterator, typename Compare>
void fl::detail::mergesort_impl ( Iterator first,
Iterator last,
Compare comp )

Definition at line 534 of file algorithm.h.

534 {
535 auto size = last - first;
536 if (size <= 16) { // Use insertion sort for small arrays (it's stable)
537 insertion_sort(first, last, comp);
538 return;
539 }
540
541 Iterator middle = first + size / 2;
542 mergesort_impl(first, middle, comp);
543 mergesort_impl(middle, last, comp);
544 merge_inplace(first, middle, last, comp);
545}
void mergesort_impl(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:534
void insertion_sort(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:298

References FL_NOEXCEPT, insertion_sort(), merge_inplace(), and mergesort_impl().

Referenced by mergesort_impl(), and fl::stable_sort().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ not_null_assert_failed()

void fl::detail::not_null_assert_failed ( const char * message)

Definition at line 24 of file not_null.cpp.hpp.

24 {
25 FL_ASSERT(false, message);
26}
#define FL_ASSERT(x, MSG)
Definition assert.h:6

References FL_ASSERT.

Referenced by fl::not_null< StringHolderPtr >::not_null(), and fl::not_null< StringHolderPtr >::operator=().

+ Here is the caller graph for this function:

◆ partition()

template<typename Iterator, typename Compare>
Iterator fl::detail::partition ( Iterator first,
Iterator last,
Compare comp )

Definition at line 338 of file algorithm.h.

338 {
339 Iterator middle = first + (last - first) / 2;
340 Iterator pivot_iter = median_of_three(first, middle, last - 1, comp);
341
342 // Move pivot to end
343 swap(*pivot_iter, *(last - 1));
344 Iterator pivot = last - 1;
345
346 Iterator i = first;
347 for (Iterator j = first; j != pivot; ++j) {
348 if (comp(*j, *pivot)) {
349 swap(*i, *j);
350 ++i;
351 }
352 }
353
354 swap(*i, *pivot);
355 return i;
356}
Iterator median_of_three(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:316

References FL_NOEXCEPT, median_of_three(), and fl::swap().

Referenced by quicksort_impl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ printLoggerDisabledError()

void fl::detail::printLoggerDisabledError ( const char * category_name,
const char * define_name )

Print error message for disabled logger (non-template helper) Called from checkLoggerEnabled template function IMPORTANT: This must NOT be inline - needs external linkage for cross-TU calls.

Definition at line 19 of file async_logger.cpp.hpp.

19 {
20 FL_ERROR(category_name << " ASYNC LOGGING NOT ENABLED. "
21 << "Add '#define " << define_name << "' before including FastLED.h");
22 }
#define FL_ERROR(X)
Definition log.h:219

References FL_ERROR.

Referenced by checkLoggerEnabled().

+ Here is the caller graph for this function:

◆ qsort_impl()

void fl::detail::qsort_impl ( char * base,
size_t nmemb,
size_t size,
qsort_compare_fn compar )

Definition at line 417 of file cstdlib.cpp.hpp.

417 {
418 if (nmemb <= 1) {
419 return;
420 }
421
422 // Use insertion sort for small arrays (threshold of 16)
423 if (nmemb <= 16) {
424 qsort_insertion_sort(base, nmemb, size, compar);
425 return;
426 }
427
428 size_t pivot_idx = qsort_partition(base, nmemb, size, compar);
429
430 // Sort left partition
431 qsort_impl(base, pivot_idx, size, compar);
432
433 // Sort right partition
434 if (pivot_idx + 1 < nmemb) {
435 qsort_impl(base + (pivot_idx + 1) * size, nmemb - pivot_idx - 1, size, compar);
436 }
437}
void qsort_impl(char *base, size_t nmemb, size_t size, qsort_compare_fn compar)
static size_t qsort_partition(char *base, size_t nmemb, size_t size, qsort_compare_fn compar)
static void qsort_insertion_sort(char *base, size_t nmemb, size_t size, qsort_compare_fn compar)

References qsort_impl(), fl::qsort_insertion_sort(), and fl::qsort_partition().

Referenced by fl::qsort(), and qsort_impl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qsort_swap()

void fl::detail::qsort_swap ( char * a,
char * b,
size_t size )

Definition at line 330 of file cstdlib.cpp.hpp.

330 {
331 if (a == b) return;
332 constexpr size_t STACK_BUF_SIZE = 64;
333 if (size <= STACK_BUF_SIZE) {
334 char tmp[STACK_BUF_SIZE];
335 memcpy(tmp, a, size);
336 memcpy(a, b, size);
337 memcpy(b, tmp, size);
338 } else {
339 for (size_t i = 0; i < size; ++i) {
340 char t = a[i];
341 a[i] = b[i];
342 b[i] = t;
343 }
344 }
345}
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT

References fl::memcpy(), and fl::t.

Referenced by fl::qsort_insertion_sort(), and fl::qsort_partition().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quicksort_impl()

template<typename Iterator, typename Compare>
void fl::detail::quicksort_impl ( Iterator first,
Iterator last,
Compare comp )

Definition at line 411 of file algorithm.h.

411 {
412 if (last - first <= 16) { // Use insertion sort for small arrays
413 insertion_sort(first, last, comp);
414 return;
415 }
416
417 Iterator pivot = partition(first, last, comp);
418 quicksort_impl(first, pivot, comp);
419 quicksort_impl(pivot + 1, last, comp);
420}
void quicksort_impl(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:411
Iterator partition(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:338

References FL_NOEXCEPT, insertion_sort(), partition(), and quicksort_impl().

Referenced by quicksort_impl(), and fl::sort().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rotate_impl()

template<typename Iterator>
void fl::detail::rotate_impl ( Iterator first,
Iterator middle,
Iterator last )

Definition at line 424 of file algorithm.h.

424 {
425 if (first == middle || middle == last) {
426 return;
427 }
428
429 Iterator next = middle;
430 while (first != next) {
431 swap(*first++, *next++);
432 if (next == last) {
433 next = middle;
434 } else if (first == middle) {
435 middle = next;
436 }
437 }
438}

References FL_NOEXCEPT, and fl::swap().

Referenced by merge_inplace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setWaitSpinBudgetUs()

void fl::detail::setWaitSpinBudgetUs ( fl::u32 budget_us)

Set the tiered-wait spin budget (microseconds).

Definition at line 33 of file wait_spin_budget.cpp.hpp.

33 {
34 sWaitSpinBudgetUs.store(budget_us);
35}

References FL_NOEXCEPT.

Referenced by CFastLED::_setWaitSpinBudgetUs().

+ Here is the caller graph for this function:

◆ sift_down()

template<typename Iterator, typename Compare>
void fl::detail::sift_down ( Iterator first,
Iterator start,
Iterator end,
Compare comp )

Definition at line 360 of file algorithm.h.

360 {
361 Iterator root = start;
362
363 while (root - first <= (end - first - 2) / 2) {
364 Iterator child = first + 2 * (root - first) + 1;
365 Iterator swap_iter = root;
366
367 if (comp(*swap_iter, *child)) {
368 swap_iter = child;
369 }
370
371 if (child + 1 <= end && comp(*swap_iter, *(child + 1))) {
372 swap_iter = child + 1;
373 }
374
375 if (swap_iter == root) {
376 return;
377 } else {
378 swap(*root, *swap_iter);
379 root = swap_iter;
380 }
381 }
382}

References fl::end(), FL_NOEXCEPT, and fl::swap().

Referenced by heap_sort(), and heapify().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sin_poly_quarterturn_()

template<typename F>
F fl::detail::sin_poly_quarterturn_ ( F x)
inline

Definition at line 170 of file math.cpp.hpp.

170 {
171 // sin(x) ≈ x - x³/6 + x⁵/120 - x⁷/5040
172 const F x2 = x * x;
173 return x * (F(1) - x2 * (F(1.0 / 6.0) - x2 * (F(1.0 / 120.0) - x2 * F(1.0 / 5040.0))));
174}

References FL_NOEXCEPT, and fl::x.

Referenced by sin_reduce_().

+ Here is the caller graph for this function:

◆ sin_reduce_()

template<typename F>
F fl::detail::sin_reduce_ ( F x)
inline

Definition at line 184 of file math.cpp.hpp.

184 {
185 const F kPi = F(3.14159265358979323846);
186 const F kTwoPi = F(6.28318530717958647692);
187 const F kPiHalf = F(1.57079632679489661923);
188 // Reduce to [-π, π]: subtract floor(x / 2π) * 2π.
189 // For the FastLED use cases we expect |x| < ~100, so this loop runs a
190 // bounded number of times. For pathological inputs we cap iterations.
191 int guard = 32;
192 while (x > kPi && guard > 0) { x -= kTwoPi; --guard; }
193 while (x < -kPi && guard > 0) { x += kTwoPi; --guard; }
194 // Map to [-π/2, π/2] using sin(π - x) = sin(x).
195 if (x > kPiHalf) x = kPi - x;
196 if (x < -kPiHalf) x = -kPi - x;
197 // [-π/2, π/2] -- the polynomial works fine here (max |x| ≈ 1.57).
198 return sin_poly_quarterturn_(x);
199}
int x
Definition simple.h:92
F sin_poly_quarterturn_(F x) FL_NOEXCEPT
Definition math.cpp.hpp:170

References FL_NOEXCEPT, sin_poly_quarterturn_(), and fl::x.

Referenced by cos_reduce_(), fl::sin_impl_double(), fl::sin_impl_float(), fl::tan_impl_double(), and fl::tan_impl_float().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ singleton_registry_get()

void * fl::detail::singleton_registry_get ( const char * key)

Definition at line 17 of file singleton.cpp.hpp.

17 {
18 for (int i = 0; i < registry_count; i++) {
19 if (fl::strcmp(registry[i].key, key) == 0) {
20 return registry[i].value;
21 }
22 }
23 return nullptr;
24}
int strcmp(const char *s1, const char *s2) FL_NOEXCEPT

References fl::strcmp(), and fl::detail::anonymous_namespace{singleton.cpp.hpp}::RegistryEntry::value.

Referenced by fl::SingletonShared< T, N >::instance().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ singleton_registry_set()

void fl::detail::singleton_registry_set ( const char * key,
void * value )

Definition at line 26 of file singleton.cpp.hpp.

26 {
27 // Check if already registered (update)
28 for (int i = 0; i < registry_count; i++) {
29 if (fl::strcmp(registry[i].key, key) == 0) {
30 registry[i].value = value;
31 return;
32 }
33 }
34 // Add new entry
35 if (registry_count < REGISTRY_MAX) {
36 registry[registry_count++] = {key, value};
37 }
38}

References fl::strcmp(), fl::type_rank< T >::value, and fl::detail::anonymous_namespace{singleton.cpp.hpp}::RegistryEntry::value.

Referenced by fl::SingletonShared< T, N >::instance().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ slab_allocator_registry_get()

void * fl::detail::slab_allocator_registry_get ( fl::size block_size,
fl::size slab_size )

Definition at line 256 of file allocator.cpp.hpp.

256 {
257 for (int i = 0; i < slab_registry_count; i++) {
258 if (slab_registry[i].block_size == block_size &&
259 slab_registry[i].slab_size == slab_size) {
260 return slab_registry[i].allocator;
261 }
262 }
263 return nullptr;
264}

References fl::detail::anonymous_namespace{allocator.cpp.hpp}::SlabRegistryEntry::allocator.

Referenced by fl::allocator_slab< T, SLAB_SIZE >::get_allocator().

+ Here is the caller graph for this function:

◆ slab_allocator_registry_set()

void fl::detail::slab_allocator_registry_set ( fl::size block_size,
fl::size slab_size,
void * allocator )

Definition at line 266 of file allocator.cpp.hpp.

266 {
267 // Check if already registered (update)
268 for (int i = 0; i < slab_registry_count; i++) {
269 if (slab_registry[i].block_size == block_size &&
270 slab_registry[i].slab_size == slab_size) {
271 slab_registry[i].allocator = allocator;
272 return;
273 }
274 }
275 // Add new entry
276 if (slab_registry_count < SLAB_REGISTRY_MAX) {
277 slab_registry[slab_registry_count++] = {block_size, slab_size, allocator};
278 }
279}

References fl::detail::anonymous_namespace{allocator.cpp.hpp}::SlabRegistryEntry::allocator.

Referenced by fl::allocator_slab< T, SLAB_SIZE >::get_allocator().

+ Here is the caller graph for this function:

◆ spread_transpose16_symbol()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::spread_transpose16_symbol ( const u8 l[16],
u8 out[16] )

Transpose one symbol of 16 lanes (16 input bytes) into 16 output bytes: 8 pulses × 2 bytes, low byte = lanes 0-7, high byte = lanes 8-15, pulse order 7..0 (out[0] = pulse 7 low).

Matches the naive layout.

Definition at line 43 of file bit_spread_lut.hpp.

43 {
44 const u32 aLo = spreadA(l[0]) | spreadA(l[1]) << 1 | spreadA(l[2]) << 2 | spreadA(l[3]) << 3 |
45 spreadA(l[4]) << 4 | spreadA(l[5]) << 5 | spreadA(l[6]) << 6 | spreadA(l[7]) << 7;
46 const u32 bLo = spreadB(l[0]) | spreadB(l[1]) << 1 | spreadB(l[2]) << 2 | spreadB(l[3]) << 3 |
47 spreadB(l[4]) << 4 | spreadB(l[5]) << 5 | spreadB(l[6]) << 6 | spreadB(l[7]) << 7;
48 const u32 aHi = spreadA(l[8]) | spreadA(l[9]) << 1 | spreadA(l[10]) << 2 | spreadA(l[11]) << 3 |
49 spreadA(l[12]) << 4 | spreadA(l[13]) << 5 | spreadA(l[14]) << 6 | spreadA(l[15]) << 7;
50 const u32 bHi = spreadB(l[8]) | spreadB(l[9]) << 1 | spreadB(l[10]) << 2 | spreadB(l[11]) << 3 |
51 spreadB(l[12]) << 4 | spreadB(l[13]) << 5 | spreadB(l[14]) << 6 | spreadB(l[15]) << 7;
52 out[0] = static_cast<u8>(aLo); out[1] = static_cast<u8>(aHi);
53 out[2] = static_cast<u8>(aLo >> 8); out[3] = static_cast<u8>(aHi >> 8);
54 out[4] = static_cast<u8>(aLo >> 16); out[5] = static_cast<u8>(aHi >> 16);
55 out[6] = static_cast<u8>(aLo >> 24); out[7] = static_cast<u8>(aHi >> 24);
56 out[8] = static_cast<u8>(bLo); out[9] = static_cast<u8>(bHi);
57 out[10] = static_cast<u8>(bLo >> 8); out[11] = static_cast<u8>(bHi >> 8);
58 out[12] = static_cast<u8>(bLo >> 16); out[13] = static_cast<u8>(bHi >> 16);
59 out[14] = static_cast<u8>(bLo >> 24); out[15] = static_cast<u8>(bHi >> 24);
60}
FASTLED_FORCE_INLINE u32 spreadA(u8 v)
Pulses 7,6,5,4 of v (byte j = bit (7-j)). Depends only on the high nibble.
FASTLED_FORCE_INLINE u32 spreadB(u8 v)
Pulses 3,2,1,0 of v (byte j = bit (3-j)). Depends only on the low nibble.

References spreadA(), and spreadB().

Referenced by wave3_transpose_16(), wave8_transpose_16(), wave8_transpose_16_bf1(), wave8_transpose_16x2_pipe2(), wave8_transpose_16x4_bf1_pipe4(), and wave8_transpose_16x4_pipe4().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ spread_transpose8_symbol()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::spread_transpose8_symbol ( const u8 l[8],
u8 out[8] )

Transpose one symbol of 8 lanes (8 input bytes) into 8 output bytes: 8 pulses × 1 byte (bit L = lane L), pulse order 7..0 (out[0] = pulse 7).

Definition at line 65 of file bit_spread_lut.hpp.

65 {
66 const u32 a = spreadA(l[0]) | spreadA(l[1]) << 1 | spreadA(l[2]) << 2 | spreadA(l[3]) << 3 |
67 spreadA(l[4]) << 4 | spreadA(l[5]) << 5 | spreadA(l[6]) << 6 | spreadA(l[7]) << 7;
68 const u32 b = spreadB(l[0]) | spreadB(l[1]) << 1 | spreadB(l[2]) << 2 | spreadB(l[3]) << 3 |
69 spreadB(l[4]) << 4 | spreadB(l[5]) << 5 | spreadB(l[6]) << 6 | spreadB(l[7]) << 7;
70 out[0] = static_cast<u8>(a); out[1] = static_cast<u8>(a >> 8);
71 out[2] = static_cast<u8>(a >> 16); out[3] = static_cast<u8>(a >> 24);
72 out[4] = static_cast<u8>(b); out[5] = static_cast<u8>(b >> 8);
73 out[6] = static_cast<u8>(b >> 16); out[7] = static_cast<u8>(b >> 24);
74}

References spreadA(), and spreadB().

Referenced by wave3_transpose_8(), wave8_transpose_8(), and wave8_transpose_8_bf1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ spreadA()

FASTLED_FORCE_INLINE u32 fl::detail::spreadA ( u8 v)

Pulses 7,6,5,4 of v (byte j = bit (7-j)). Depends only on the high nibble.

Definition at line 35 of file bit_spread_lut.hpp.

35{ return kSpreadNibble[v >> 4]; }
constexpr u32 kSpreadNibble[16]
kSpreadNibble[n] places the 4 bits of nibble n at bit 0 of 4 separate bytes: byte0 = bit3(n),...

References FASTLED_FORCE_INLINE, and kSpreadNibble.

Referenced by spread_transpose16_symbol(), spread_transpose8_symbol(), and wave8_transpose_4_bf1().

+ Here is the caller graph for this function:

◆ spreadB()

FASTLED_FORCE_INLINE u32 fl::detail::spreadB ( u8 v)

Pulses 3,2,1,0 of v (byte j = bit (3-j)). Depends only on the low nibble.

Definition at line 37 of file bit_spread_lut.hpp.

37{ return kSpreadNibble[v & 0x0Fu]; }

References FASTLED_FORCE_INLINE, and kSpreadNibble.

Referenced by spread_transpose16_symbol(), spread_transpose8_symbol(), and wave8_transpose_4_bf1().

+ Here is the caller graph for this function:

◆ sqrt_newton_()

template<typename F>
F fl::detail::sqrt_newton_ ( F value)
inline

Definition at line 151 of file math.cpp.hpp.

151 {
152 if (value <= F(0)) return F(0);
153 // Initial estimate: x_0 = value / 2. Pure-arithmetic, no bit-cast needed.
154 // Newton converges quadratically so 5-6 iterations is plenty even from a
155 // crude start.
156 F x = value;
157 if (x > F(1)) x = F(1) + (x - F(1)) * F(0.5); // bias toward 1 for fast convergence
158 for (int i = 0; i < 6; ++i) {
159 if (x == F(0)) break;
160 x = F(0.5) * (x + value / x);
161 }
162 return x;
163}

References FL_NOEXCEPT, fl::type_rank< T >::value, and fl::x.

Referenced by fl::asin_impl_double(), fl::asin_impl_float(), fl::hypot_impl_double(), fl::hypot_impl_float(), fl::sqrt_impl_double(), and fl::sqrt_impl_float().

+ Here is the caller graph for this function:

◆ test_encoder() [1/2]

template<typename T>
bool fl::detail::test_encoder ( ...)
constexpr

Definition at line 33 of file clockless_encoder.h.

33{ return false; }

References FL_NOEXCEPT.

◆ test_encoder() [2/2]

template<typename T>
auto fl::detail::test_encoder ( int ) -> decltype(T::ENCODER, true)
constexpr

Definition at line 31 of file clockless_encoder.h.

31{ return true; }

References FL_NOEXCEPT.

◆ to_string()

void fl::detail::to_string ( const fl::u16 * bit_data,
fl::u32 bit_count,
string * dst )

Definition at line 9 of file bitset.cpp.hpp.

9 {
10 fl::string& result = *dst;
11 constexpr fl::u32 bits_per_block = 8 * sizeof(fl::u16); // 16 bits per block
12
13 for (fl::u32 i = 0; i < bit_count; ++i) {
14 const fl::u32 block_idx = i / bits_per_block;
15 const fl::u32 bit_offset = i % bits_per_block;
16
17 // Extract the bit from the block
18 bool bit_value = (bit_data[block_idx] >> bit_offset) & 1;
19 result.append(bit_value ? "1" : "0");
20 }
21}

Referenced by FL_DISABLE_WARNING(), and fl::bitset_dynamic::to_string().

+ Here is the caller graph for this function:

◆ UpscalePaletteInterpolated()

template<typename TSrcPalette, typename TDestPalette>
void fl::detail::UpscalePaletteInterpolated ( const TSrcPalette & srcpal,
TDestPalette & destpal )

Definition at line 1200 of file colorutils.cpp.hpp.

1201 {
1202 const fl::u16 dest_size =
1203 sizeof(destpal.entries) / sizeof(destpal.entries[0]);
1204 for (fl::u16 i = 0; i < dest_size; ++i) {
1205 destpal[static_cast<fl::u8>(i)] =
1206 ColorFromPalette(srcpal, static_cast<fl::u8>(i));
1207 }
1208}
unsigned char u8
Definition s16x16x4.h:132
CRGB ColorFromPalette(const CRGBPalette16 &pal, fl::u8 index, fl::u8 brightness, TBlendType blendType)

References fl::ColorFromPalette().

Referenced by fl::UpscalePalette(), fl::UpscalePalette(), fl::UpscalePalette(), and fl::UpscalePalette().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ UpscalePaletteRepeat()

template<typename TSrcPalette, typename TDestPalette>
void fl::detail::UpscalePaletteRepeat ( const TSrcPalette & srcpal,
TDestPalette & destpal )

Definition at line 1185 of file colorutils.cpp.hpp.

1186 {
1187 const fl::u16 src_size = sizeof(srcpal.entries) / sizeof(srcpal.entries[0]);
1188 const fl::u16 dest_size =
1189 sizeof(destpal.entries) / sizeof(destpal.entries[0]);
1190 const fl::u16 repeat = dest_size / src_size;
1191 for (fl::u16 i = 0; i < src_size; ++i) {
1192 const fl::u16 start = i * repeat;
1193 for (fl::u16 j = 0; j < repeat; ++j) {
1194 destpal[static_cast<fl::u8>(start + j)] = srcpal[static_cast<fl::u8>(i)];
1195 }
1196 }
1197}

Referenced by fl::UpscalePalette(), and fl::UpscalePalette().

+ Here is the caller graph for this function:

◆ wave3_convert_byte_to_wave3byte()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave3_convert_byte_to_wave3byte ( u8 byte_value,
const Wave3BitExpansionLut & lut,
Wave3Byte * output )

Helper: Convert byte to Wave3Byte using nibble LUT (internal use only)

Note
Inline implementation for ISR performance

Definition at line 27 of file wave3.hpp.

29 {
30 // High nibble → 12 bits, low nibble → 12 bits, total 24 bits = 3 bytes
31 u16 high_pattern = lut.lut[(byte_value >> 4) & 0xF];
32 u16 low_pattern = lut.lut[byte_value & 0xF];
33
34 // Pack 24 bits into 3 bytes (MSB first):
35 // Byte 0: bits [23..16] = high_pattern[11..4]
36 // Byte 1: bits [15..8] = high_pattern[3..0] | low_pattern[11..8]
37 // Byte 2: bits [7..0] = low_pattern[7..0]
38 output->data[0] = (u8)(high_pattern >> 4);
39 output->data[1] = (u8)(((high_pattern & 0xF) << 4) | ((low_pattern >> 8) & 0xF));
40 output->data[2] = (u8)(low_pattern & 0xFF);
41}

Referenced by fl::wave3(), fl::wave3Transpose_16(), fl::wave3Transpose_2(), fl::wave3Transpose_4(), and fl::wave3Transpose_8().

+ Here is the caller graph for this function:

◆ wave3_transpose_16()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave3_transpose_16 ( const Wave3Byte lane_waves[16],
u8 output[16 *sizeof(Wave3Byte)] )

Transpose 16 lanes of Wave3Byte data into interleaved format.

Parameters
lane_wavesArray of 16 Wave3Byte structures
outputOutput buffer (48 bytes = 16 * 3)

Spread-LUT transpose (#2533): ~1.9× faster than the unrolled naive on the ESP32-P4 (RV32), bit-exact. See bit_spread_lut.hpp. Each 16-lane sample is 2 output bytes: low = lanes 0-7, high = lanes 8-15. (wave3 = 3 symbols.)

Definition at line 170 of file wave3.hpp.

171 {
172 for (int symbol_idx = 0; symbol_idx < 3; symbol_idx++) {
173 u8 l[16];
174 for (int lane = 0; lane < 16; lane++) {
175 l[lane] = lane_waves[lane].data[symbol_idx];
176 }
177 spread_transpose16_symbol(l, output + symbol_idx * 16);
178 }
179}
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose16_symbol(const u8 l[16], u8 out[16])
Transpose one symbol of 16 lanes (16 input bytes) into 16 output bytes: 8 pulses × 2 bytes,...
u8 data[3]
Definition wave3.h:21

References fl::Wave3Byte::data, and spread_transpose16_symbol().

Referenced by fl::wave3Transpose_16().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave3_transpose_2()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave3_transpose_2 ( const Wave3Byte lane_waves[2],
u8 output[2 *sizeof(Wave3Byte)] )

Transpose 2 lanes of Wave3Byte data into interleaved format.

Parameters
lane_wavesArray of 2 Wave3Byte structures
outputOutput buffer (6 bytes = 2 * 3)

Definition at line 51 of file wave3.hpp.

52 {
53 // Wave3 produces 3 symbols per LED byte (one byte per symbol for each lane).
54 // For 2 lanes: interleave bits from both lanes into 2 bytes per symbol.
55 // Each symbol byte has 8 bits. With 2 lanes we produce 2 bytes per symbol
56 // using the same bit-spreading as wave8_transpose_2.
57
58 for (int symbol_idx = 0; symbol_idx < 3; symbol_idx++) {
59 u8 l0 = lane_waves[0].data[symbol_idx];
60 u8 l1 = lane_waves[1].data[symbol_idx];
61
62 // Interleave bits: for each bit position, lane0 goes to odd bits, lane1 to even bits
63 u16 interleaved = 0;
64 for (int bit = 0; bit < 8; bit++) {
65 u16 b0 = (l0 >> bit) & 1;
66 u16 b1 = (l1 >> bit) & 1;
67 interleaved |= (b1 << (bit * 2)); // even positions
68 interleaved |= (b0 << (bit * 2 + 1)); // odd positions
69 }
70
71 output[symbol_idx * 2] = (u8)(interleaved >> 8);
72 output[symbol_idx * 2 + 1] = (u8)(interleaved & 0xFF);
73 }
74}

References fl::Wave3Byte::data.

Referenced by fl::wave3Transpose_2().

+ Here is the caller graph for this function:

◆ wave3_transpose_4()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave3_transpose_4 ( const Wave3Byte lane_waves[4],
u8 output[4 *sizeof(Wave3Byte)] )

Transpose 4 lanes of Wave3Byte data into interleaved format.

Parameters
lane_wavesArray of 4 Wave3Byte structures
outputOutput buffer (12 bytes = 4 * 3)

Definition at line 84 of file wave3.hpp.

85 {
86 for (int symbol_idx = 0; symbol_idx < 3; symbol_idx++) {
87 u8 l0 = lane_waves[0].data[symbol_idx];
88 u8 l1 = lane_waves[1].data[symbol_idx];
89 u8 l2 = lane_waves[2].data[symbol_idx];
90 u8 l3 = lane_waves[3].data[symbol_idx];
91
92 // 4 output bytes per symbol (2 pulses per byte × 4 lanes)
93 // Same bit layout as wave8_transpose_4
94 output[symbol_idx * 4 + 0] =
95 ((l3 >> 7) & 1) << 7 |
96 ((l2 >> 7) & 1) << 6 |
97 ((l1 >> 7) & 1) << 5 |
98 ((l0 >> 7) & 1) << 4 |
99 ((l3 >> 6) & 1) << 3 |
100 ((l2 >> 6) & 1) << 2 |
101 ((l1 >> 6) & 1) << 1 |
102 ((l0 >> 6) & 1);
103
104 output[symbol_idx * 4 + 1] =
105 ((l3 >> 5) & 1) << 7 |
106 ((l2 >> 5) & 1) << 6 |
107 ((l1 >> 5) & 1) << 5 |
108 ((l0 >> 5) & 1) << 4 |
109 ((l3 >> 4) & 1) << 3 |
110 ((l2 >> 4) & 1) << 2 |
111 ((l1 >> 4) & 1) << 1 |
112 ((l0 >> 4) & 1);
113
114 output[symbol_idx * 4 + 2] =
115 ((l3 >> 3) & 1) << 7 |
116 ((l2 >> 3) & 1) << 6 |
117 ((l1 >> 3) & 1) << 5 |
118 ((l0 >> 3) & 1) << 4 |
119 ((l3 >> 2) & 1) << 3 |
120 ((l2 >> 2) & 1) << 2 |
121 ((l1 >> 2) & 1) << 1 |
122 ((l0 >> 2) & 1);
123
124 output[symbol_idx * 4 + 3] =
125 ((l3 >> 1) & 1) << 7 |
126 ((l2 >> 1) & 1) << 6 |
127 ((l1 >> 1) & 1) << 5 |
128 ((l0 >> 1) & 1) << 4 |
129 ((l3 >> 0) & 1) << 3 |
130 ((l2 >> 0) & 1) << 2 |
131 ((l1 >> 0) & 1) << 1 |
132 ((l0 >> 0) & 1);
133 }
134}

References fl::Wave3Byte::data.

Referenced by fl::wave3Transpose_4().

+ Here is the caller graph for this function:

◆ wave3_transpose_8()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave3_transpose_8 ( const Wave3Byte lane_waves[8],
u8 output[8 *sizeof(Wave3Byte)] )

Transpose 8 lanes of Wave3Byte data into interleaved format.

Parameters
lane_wavesArray of 8 Wave3Byte structures
outputOutput buffer (24 bytes = 8 * 3)

Spread-LUT transpose (#2533): ~1.9× faster than the unrolled naive on the ESP32-P4 (RV32), bit-exact. See bit_spread_lut.hpp. (wave3 = 3 symbols.)

Definition at line 147 of file wave3.hpp.

148 {
149 for (int symbol_idx = 0; symbol_idx < 3; symbol_idx++) {
150 u8 l[8];
151 for (int lane = 0; lane < 8; lane++) {
152 l[lane] = lane_waves[lane].data[symbol_idx];
153 }
154 spread_transpose8_symbol(l, output + symbol_idx * 8);
155 }
156}
FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void spread_transpose8_symbol(const u8 l[8], u8 out[8])
Transpose one symbol of 8 lanes (8 input bytes) into 8 output bytes: 8 pulses × 1 byte (bit L = lane ...

References fl::Wave3Byte::data, and spread_transpose8_symbol().

Referenced by fl::wave3Transpose_8().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_convert_byte_to_wave8byte()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_convert_byte_to_wave8byte ( u8 byte_value,
const Wave8BitExpansionLut & lut,
Wave8Byte * output )

Helper: Convert byte to Wave8Byte using nibble LUT (internal use only)

Note
Inline implementation for ISR performance

Definition at line 47 of file wave8.hpp.

49 {
50 // ISR-optimized copy: Copy high nibble (4 bytes = 1 x uint32_t)
51 const Wave8Bit *high_nibble_data = lut.lut[(byte_value >> 4) & 0xF];
52 isr::memcpy_32(fl::bit_cast_ptr<u32>(&output->symbols[0]),
53 fl::bit_cast_ptr<const u32>(high_nibble_data),
54 1); // 4 bytes = 1 x uint32_t
55
56 // ISR-optimized copy: Copy low nibble (4 bytes = 1 x uint32_t)
57 const Wave8Bit *low_nibble_data = lut.lut[byte_value & 0xF];
58 isr::memcpy_32(fl::bit_cast_ptr<u32>(&output->symbols[4]),
59 fl::bit_cast_ptr<const u32>(low_nibble_data),
60 1); // 4 bytes = 1 x uint32_t
61}
FL_OPTIMIZE_FUNCTION FL_IRAM FASTLED_FORCE_INLINE void memcpy_32(u32 *FL_RESTRICT_PARAM dst, const u32 *FL_RESTRICT_PARAM src, size_t count)
ISR-optimized 32-bit block copy for 4-byte aligned memory.
Definition memcpy.h:32
To * bit_cast_ptr(void *storage) FL_NOEXCEPT
Definition bit_cast.h:60
Type-safe container for packed 8-bit wave pulse pattern.
Definition wave8.h:22

References fl::bit_cast_ptr(), and fl::isr::memcpy_32().

Referenced by fl::wave8(), fl::wave8Transpose_16(), fl::wave8Transpose_2(), fl::wave8Transpose_4(), and fl::wave8Transpose_8().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_expand_byte()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_expand_byte ( u8 byte_value,
const Wave8ByteExpansionLut & lut,
Wave8Byte * output )

Byte-indexed expansion (#2526): one indexed 8-byte copy.

Single lookup (no >>4/mask, no second index) into the 256×8 byte LUT; bit-identical to wave8_convert_byte_to_wave8byte(). ~half the index/issue work for the same memory traffic — the win on the in-order RV32 core.

Definition at line 69 of file wave8.hpp.

71 {
73 fl::bit_cast_ptr<const u32>(&lut.lut[byte_value]),
74 2); // 8 bytes = 2 x uint32_t
75}

References fl::bit_cast_ptr(), and fl::isr::memcpy_32().

Referenced by fl::wave8Transpose_16(), fl::wave8Transpose_16x2_pipe2(), fl::wave8Transpose_16x4_pipe4(), fl::wave8Transpose_2(), fl::wave8Transpose_4(), and fl::wave8Transpose_8().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_16()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_16 ( const Wave8Byte lane_waves[16],
u8 output[16 *sizeof(Wave8Byte)] )

Transpose 16 lanes of Wave8Byte data into interleaved format.

Parameters
lane_wavesArray of 16 Wave8Byte structures
outputOutput buffer (128 bytes)

Spread-LUT transpose (#2533): ~1.98× faster than the unrolled naive on the ESP32-P4 (RV32) — 6649→3353 us/frame, bit-exact. Two-pass (two 8x8 via u32), u64 SWAR, and Hacker's-Delight all lost to this on the in-order core; the winning shape is independent table-lookup + shift + OR-reduce (native u32, no dependency chain). See bit_spread_lut.hpp. Each 16-lane sample is 2 output bytes: low = lanes 0-7, high = lanes 8-15.

Definition at line 231 of file wave8.hpp.

232 {
233 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
234 u8 l[16];
235 for (int lane = 0; lane < 16; lane++) {
236 l[lane] = lane_waves[lane].symbols[symbol_idx].data;
237 }
238 spread_transpose16_symbol(l, output + symbol_idx * 16);
239 }
240}

References spread_transpose16_symbol().

Referenced by fl::wave8Transpose_16(), and fl::wave8Transpose_16().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_16_bf1()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_16_bf1 ( const u8 lanes[16],
u8 W0,
u8 W1,
u8 output[16 *sizeof(Wave8Byte)] )

BF1: chipset-aware direct encode for Wave8 16-lane (#2548 deep-dive).

Bypasses the byte_lut entirely by exploiting the algebraic identity: output_bit(s, p, lane) = M0_p XOR (input_bit_(7-s)_of_lane AND D_p) where W0/W1 are the bit-0 / bit-1 waveform patterns (chipset constants), M0_p = (W0 >> (7-p)) & 1, D_p = M0_p XOR M1_p. The bit-transpose of input lane bytes (giving the per-symbol column bytes) is computed ONCE by spread_transpose16_symbol — replacing the prior 8 calls (one per symbol) plus the 16 byte_lut expansions.

Bit-identical to wave8_transpose_16(expand(lanes_input), output). Works for ANY Wave8 chipset/timing — W0/W1 are derived from the byte_lut at runtime.

Measured 6 822 → 1 757 µs/frame (3.88× faster than pipe4, 5.49× vs baseline) when fused with pipe4 (#2548 final).

Definition at line 315 of file wave8.hpp.

317 {
318 u8 d_mask[8];
319 u8 m0_mask[8];
320 const u8 D_byte = W0 ^ W1;
321 for (int p = 0; p < 8; ++p) {
322 const int shift = 7 - p;
323 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
324 m0_mask[p] = ((W0 >> shift) & 1) ? 0xFFu : 0x00u;
325 }
326 // Bit-transpose: spread_transpose16_symbol on input bytes gives
327 // cols[2s+h] = byte where bit L = bit(7-s) of lanes[L+8h].
328 u8 cols[16];
329 spread_transpose16_symbol(lanes, cols);
330 for (int s = 0; s < 8; ++s) {
331 const u8 col_lo = cols[2 * s + 0];
332 const u8 col_hi = cols[2 * s + 1];
333 for (int p = 0; p < 8; ++p) {
334 output[s * 16 + p * 2 + 0] = m0_mask[p] ^ (col_lo & d_mask[p]);
335 output[s * 16 + p * 2 + 1] = m0_mask[p] ^ (col_hi & d_mask[p]);
336 }
337 }
338}
@ W1
White is second.
Definition eorder.h:26
@ W0
White is first.
Definition eorder.h:27

References spread_transpose16_symbol(), fl::W0, and fl::W1.

Referenced by fl::wave8Transpose_16_bf1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_16x2_pipe2()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_16x2_pipe2 ( const Wave8Byte lane_waves_a[16],
const Wave8Byte lane_waves_b[16],
u8 output_a[16 *sizeof(Wave8Byte)],
u8 output_b[16 *sizeof(Wave8Byte)] )

Pipe2: transpose 16-lane × 2-byte-positions in one fused call.

Result is bit-identical to two sequential wave8_transpose_16 calls; the win comes from interleaving the two independent OR-trees inside the symbol loop so the in-order RV32 P4 can fill load-use stall cycles from position A with ALU ops from position B (and vice versa). Measured +26% / frame vs sequential calls on P4 v1.3 (#2548).

Definition at line 249 of file wave8.hpp.

252 {
253 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
254 u8 la[16];
255 u8 lb[16];
256 for (int lane = 0; lane < 16; lane++) {
257 la[lane] = lane_waves_a[lane].symbols[symbol_idx].data;
258 lb[lane] = lane_waves_b[lane].symbols[symbol_idx].data;
259 }
260 spread_transpose16_symbol(la, output_a + symbol_idx * 16);
261 spread_transpose16_symbol(lb, output_b + symbol_idx * 16);
262 }
263}

References spread_transpose16_symbol().

Referenced by fl::wave8Transpose_16x2_pipe2().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_16x4_bf1_pipe4()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_16x4_bf1_pipe4 ( const u8 lanes_a[16],
const u8 lanes_b[16],
const u8 lanes_c[16],
const u8 lanes_d[16],
u8 W0,
u8 W1,
u8 output_a[16 *sizeof(Wave8Byte)],
u8 output_b[16 *sizeof(Wave8Byte)],
u8 output_c[16 *sizeof(Wave8Byte)],
u8 output_d[16 *sizeof(Wave8Byte)] )

BF1 + pipe4: 4-position software-pipelined BF1 (#2548 deep-dive).

Combines BF1's algorithmic reduction (1 transpose per byte-position instead of 8) with pipe4's cross-position ILP. Empirical peak of all prototypes: 1 757 µs/frame vs 9 651 baseline (5.49×).

Definition at line 464 of file wave8.hpp.

472 {
473 u8 d_mask[8];
474 u8 m0_mask[8];
475 const u8 D_byte = W0 ^ W1;
476 for (int p = 0; p < 8; ++p) {
477 const int shift = 7 - p;
478 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
479 m0_mask[p] = ((W0 >> shift) & 1) ? 0xFFu : 0x00u;
480 }
481 u8 cols_a[16], cols_b[16], cols_c[16], cols_d[16];
482 spread_transpose16_symbol(lanes_a, cols_a);
483 spread_transpose16_symbol(lanes_b, cols_b);
484 spread_transpose16_symbol(lanes_c, cols_c);
485 spread_transpose16_symbol(lanes_d, cols_d);
486 for (int s = 0; s < 8; ++s) {
487 const u8 al = cols_a[2*s + 0], ah = cols_a[2*s + 1];
488 const u8 bl = cols_b[2*s + 0], bh = cols_b[2*s + 1];
489 const u8 cl = cols_c[2*s + 0], ch = cols_c[2*s + 1];
490 const u8 dl = cols_d[2*s + 0], dh = cols_d[2*s + 1];
491 for (int p = 0; p < 8; ++p) {
492 const u8 dm = d_mask[p], mm = m0_mask[p];
493 output_a[s*16 + p*2 + 0] = mm ^ (al & dm);
494 output_a[s*16 + p*2 + 1] = mm ^ (ah & dm);
495 output_b[s*16 + p*2 + 0] = mm ^ (bl & dm);
496 output_b[s*16 + p*2 + 1] = mm ^ (bh & dm);
497 output_c[s*16 + p*2 + 0] = mm ^ (cl & dm);
498 output_c[s*16 + p*2 + 1] = mm ^ (ch & dm);
499 output_d[s*16 + p*2 + 0] = mm ^ (dl & dm);
500 output_d[s*16 + p*2 + 1] = mm ^ (dh & dm);
501 }
502 }
503}

References spread_transpose16_symbol(), fl::W0, and fl::W1.

Referenced by fl::wave8Transpose_16x4_bf1_pipe4().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_16x4_pipe4()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_16x4_pipe4 ( const Wave8Byte lane_waves_a[16],
const Wave8Byte lane_waves_b[16],
const Wave8Byte lane_waves_c[16],
const Wave8Byte lane_waves_d[16],
u8 output_a[16 *sizeof(Wave8Byte)],
u8 output_b[16 *sizeof(Wave8Byte)],
u8 output_c[16 *sizeof(Wave8Byte)],
u8 output_d[16 *sizeof(Wave8Byte)] )

Pipe4: transpose 16-lane × 4-byte-positions in one fused call.

Bit-identical to four sequential wave8_transpose_16 calls. Extends the pipe2 idea to 4 positions — empirically the peak of the curve on the in-order RV32 P4 core (#2548). pipe2 saved 26% over baseline, pipe3 36%, pipe4 41%, pipe6 regressed to 94% (register spill). Stays within the 32-GPR budget: 4 × 4 = 16 OR-tree accumulators + ~8 misc GPRs = ~24 live; pipe6 would push this past 32.

Definition at line 273 of file wave8.hpp.

280 {
281 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
282 u8 la[16];
283 u8 lb[16];
284 u8 lc[16];
285 u8 ld[16];
286 for (int lane = 0; lane < 16; lane++) {
287 la[lane] = lane_waves_a[lane].symbols[symbol_idx].data;
288 lb[lane] = lane_waves_b[lane].symbols[symbol_idx].data;
289 lc[lane] = lane_waves_c[lane].symbols[symbol_idx].data;
290 ld[lane] = lane_waves_d[lane].symbols[symbol_idx].data;
291 }
292 spread_transpose16_symbol(la, output_a + symbol_idx * 16);
293 spread_transpose16_symbol(lb, output_b + symbol_idx * 16);
294 spread_transpose16_symbol(lc, output_c + symbol_idx * 16);
295 spread_transpose16_symbol(ld, output_d + symbol_idx * 16);
296 }
297}

References spread_transpose16_symbol().

Referenced by fl::wave8Transpose_16x4_pipe4().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_2()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_2 ( const Wave8Byte lane_waves[2],
u8 output[2 *sizeof(Wave8Byte)] )

Transpose 2 lanes of Wave8Byte data into interleaved format.

Parameters
lane_wavesArray of 2 Wave8Byte structures (lane[0]=even bits, lane[1]=odd bits)
outputOutput buffer (16 bytes)

Definition at line 103 of file wave8.hpp.

104 {
105 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
106 u16 interleaved = 0;
107 // NOTE: FL_WAVE8_SPREAD_TO_16 macro treats first param as ODD bits, second as EVEN bits
108 // This matches wave8Untranspose_2 expectations: lane[0]→odd, lane[1]→even
109 FL_WAVE8_SPREAD_TO_16(lane_waves[0].symbols[symbol_idx].data,
110 lane_waves[1].symbols[symbol_idx].data,
111 interleaved);
112
113 output[symbol_idx * 2] = (u8)(interleaved >> 8); // High byte first (MSB pulses 4-7)
114 output[symbol_idx * 2 + 1] = (u8)(interleaved & 0xFF); // Low byte second (LSB pulses 0-3)
115 }
116}
#define FL_WAVE8_SPREAD_TO_16(lane_u8_0, lane_u8_1, out_16)
Definition wave8.hpp:81

References FL_WAVE8_SPREAD_TO_16.

Referenced by fl::wave8Transpose_2(), and fl::wave8Transpose_2().

+ Here is the caller graph for this function:

◆ wave8_transpose_2_bf1()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_2_bf1 ( const u8 lanes[2],
u8 W0,
u8 W1,
u8 output[2 *sizeof(Wave8Byte)] )

BF1 for 2-lane Wave8.

Output: 8 symbols × 2 bytes = 16 bytes. Each byte packs 4 pulses × 2 lanes bit-interleaved (lane 1 in even bit positions, lane 0 in odd). High byte (output[s*2 + 0]) holds bf1-pulse indices 0..3 with q=0 → pulse 3 and q=3 → pulse 0; low byte holds bf1-pulse indices 4..7 with q=0 → pulse 7 and q=3 → pulse 4. Layout matches wave8_transpose_2's LUT-based packing (see FL_WAVE8_SPREAD_TO_16 / kTranspose4_16_LUT).

Definition at line 417 of file wave8.hpp.

419 {
420 u8 d_mask[8];
421 u8 m0_mask[8];
422 const u8 D_byte = W0 ^ W1;
423 for (int p = 0; p < 8; ++p) {
424 const int shift = 7 - p;
425 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
426 m0_mask[p] = ((W0 >> shift) & 1) ? 0xFFu : 0x00u;
427 }
428 for (int s = 0; s < 8; ++s) {
429 const int bit_idx = 7 - s;
430 const u8 b0 = static_cast<u8>((lanes[0] >> bit_idx) & 1u);
431 const u8 b1 = static_cast<u8>((lanes[1] >> bit_idx) & 1u);
432 u8 byte_hi = 0;
433 u8 byte_lo = 0;
434 for (int q = 0; q < 4; ++q) {
435 // Reference `wave8_transpose_2` lands chipset-byte bit (4+q) at
436 // high-byte bit position (2*q) for lane 1 (even) / (2*q+1) for
437 // lane 0 (odd). Chipset-byte bit (4+q) corresponds to bf1
438 // pulse index (3 - q) because bf1 numbers pulse p ↔ chipset bit
439 // (7 - p). Similarly the low byte uses chipset bits 0..3, which
440 // map to bf1 pulses 7..4.
441 const int p_hi = 3 - q;
442 const int p_lo = 7 - q;
443 const u8 m0_p_hi = static_cast<u8>(m0_mask[p_hi] & 1u);
444 const u8 d_p_hi = static_cast<u8>(d_mask[p_hi] & 1u);
445 const u8 m0_p_lo = static_cast<u8>(m0_mask[p_lo] & 1u);
446 const u8 d_p_lo = static_cast<u8>(d_mask[p_lo] & 1u);
447 const u8 v0_hi = static_cast<u8>(m0_p_hi ^ (b0 & d_p_hi));
448 const u8 v1_hi = static_cast<u8>(m0_p_hi ^ (b1 & d_p_hi));
449 const u8 v0_lo = static_cast<u8>(m0_p_lo ^ (b0 & d_p_lo));
450 const u8 v1_lo = static_cast<u8>(m0_p_lo ^ (b1 & d_p_lo));
451 byte_hi |= static_cast<u8>((v1_hi << (2 * q)) | (v0_hi << (2 * q + 1)));
452 byte_lo |= static_cast<u8>((v1_lo << (2 * q)) | (v0_lo << (2 * q + 1)));
453 }
454 output[s * 2 + 0] = byte_hi;
455 output[s * 2 + 1] = byte_lo;
456 }
457}

References fl::W0, and fl::W1.

Referenced by fl::wave8Transpose_2_bf1().

+ Here is the caller graph for this function:

◆ wave8_transpose_4()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_4 ( const Wave8Byte lane_waves[4],
u8 output[4 *sizeof(Wave8Byte)] )

Transpose 4 lanes of Wave8Byte data into interleaved format.

Parameters
lane_wavesArray of 4 Wave8Byte structures
outputOutput buffer (32 bytes)

Definition at line 126 of file wave8.hpp.

127 {
128 // Each symbol (Wave8Bit) has 8 pulses
129 // With 4 lanes, we produce 4 bytes per symbol (2 pulses per byte × 4 lanes)
130 // Output format: [L3_P7, L2_P7, L1_P7, L0_P7, L3_P6, L2_P6, L1_P6, L0_P6, ...]
131 //
132 // OPTIMIZED VERSION: Fully unrolled direct extraction (4.0x speedup vs baseline)
133 // Based on successful 16-lane pattern that achieved 8x speedup
134 // Eliminates triple-nested loops by explicitly extracting and packing bits
135
136 // Process each symbol (8 iterations)
137 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
138 // Pre-load all 4 lane bytes into registers
139 u8 l0 = lane_waves[0].symbols[symbol_idx].data;
140 u8 l1 = lane_waves[1].symbols[symbol_idx].data;
141 u8 l2 = lane_waves[2].symbols[symbol_idx].data;
142 u8 l3 = lane_waves[3].symbols[symbol_idx].data;
143
144 // Explicitly construct all 4 output bytes
145 // Each output byte contains 2 pulses from all 4 lanes
146 // Bit layout: [L3_hi, L2_hi, L1_hi, L0_hi, L3_lo, L2_lo, L1_lo, L0_lo]
147
148 // Byte 0: pulses 7 (hi) and 6 (lo)
149 output[symbol_idx * 4 + 0] =
150 ((l3 >> 7) & 1) << 7 |
151 ((l2 >> 7) & 1) << 6 |
152 ((l1 >> 7) & 1) << 5 |
153 ((l0 >> 7) & 1) << 4 |
154 ((l3 >> 6) & 1) << 3 |
155 ((l2 >> 6) & 1) << 2 |
156 ((l1 >> 6) & 1) << 1 |
157 ((l0 >> 6) & 1);
158
159 // Byte 1: pulses 5 (hi) and 4 (lo)
160 output[symbol_idx * 4 + 1] =
161 ((l3 >> 5) & 1) << 7 |
162 ((l2 >> 5) & 1) << 6 |
163 ((l1 >> 5) & 1) << 5 |
164 ((l0 >> 5) & 1) << 4 |
165 ((l3 >> 4) & 1) << 3 |
166 ((l2 >> 4) & 1) << 2 |
167 ((l1 >> 4) & 1) << 1 |
168 ((l0 >> 4) & 1);
169
170 // Byte 2: pulses 3 (hi) and 2 (lo)
171 output[symbol_idx * 4 + 2] =
172 ((l3 >> 3) & 1) << 7 |
173 ((l2 >> 3) & 1) << 6 |
174 ((l1 >> 3) & 1) << 5 |
175 ((l0 >> 3) & 1) << 4 |
176 ((l3 >> 2) & 1) << 3 |
177 ((l2 >> 2) & 1) << 2 |
178 ((l1 >> 2) & 1) << 1 |
179 ((l0 >> 2) & 1);
180
181 // Byte 3: pulses 1 (hi) and 0 (lo)
182 output[symbol_idx * 4 + 3] =
183 ((l3 >> 1) & 1) << 7 |
184 ((l2 >> 1) & 1) << 6 |
185 ((l1 >> 1) & 1) << 5 |
186 ((l0 >> 1) & 1) << 4 |
187 ((l3 >> 0) & 1) << 3 |
188 ((l2 >> 0) & 1) << 2 |
189 ((l1 >> 0) & 1) << 1 |
190 ((l0 >> 0) & 1);
191 }
192}

Referenced by fl::wave8Transpose_4(), and fl::wave8Transpose_4().

+ Here is the caller graph for this function:

◆ wave8_transpose_4_bf1()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_4_bf1 ( const u8 lanes[4],
u8 W0,
u8 W1,
u8 output[4 *sizeof(Wave8Byte)] )

BF1 for 4-lane Wave8.

Output: 8 symbols × 4 bytes = 32 bytes. Each byte packs 2 pulses × 4 lanes — high nibble = earlier pulse, low nibble = later pulse; within each nibble, lanes 0..3 in bits 0..3.

Definition at line 370 of file wave8.hpp.

372 {
373 u8 d_mask[8];
374 u8 m0_mask[8];
375 const u8 D_byte = W0 ^ W1;
376 for (int p = 0; p < 8; ++p) {
377 const int shift = 7 - p;
378 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
379 m0_mask[p] = ((W0 >> shift) & 1) ? 0xFFu : 0x00u;
380 }
381 // Bit transpose: cols[s] (low nibble) = bit(7-s) of lanes 0..3.
382 // spreadA(lanes[L]) puts the 4 high-nibble bits of lanes[L] into bit 0 of
383 // 4 separate bytes; OR'd across lanes with shifts gives 4 bytes (cols[0..3]).
384 const u32 aLo = spreadA(lanes[0]) | (spreadA(lanes[1]) << 1)
385 | (spreadA(lanes[2]) << 2) | (spreadA(lanes[3]) << 3);
386 const u32 bLo = spreadB(lanes[0]) | (spreadB(lanes[1]) << 1)
387 | (spreadB(lanes[2]) << 2) | (spreadB(lanes[3]) << 3);
388 u8 cols[8];
389 cols[0] = static_cast<u8>(aLo);
390 cols[1] = static_cast<u8>(aLo >> 8);
391 cols[2] = static_cast<u8>(aLo >> 16);
392 cols[3] = static_cast<u8>(aLo >> 24);
393 cols[4] = static_cast<u8>(bLo);
394 cols[5] = static_cast<u8>(bLo >> 8);
395 cols[6] = static_cast<u8>(bLo >> 16);
396 cols[7] = static_cast<u8>(bLo >> 24);
397 for (int s = 0; s < 8; ++s) {
398 const u8 col = cols[s]; // bits 0..3 = lanes 0..3
399 for (int k = 0; k < 4; ++k) {
400 const int p_hi = 2 * k;
401 const int p_lo = 2 * k + 1;
402 const u8 hi = static_cast<u8>((m0_mask[p_hi] & 0xF0u) ^ ((col << 4) & d_mask[p_hi]));
403 const u8 lo = static_cast<u8>((m0_mask[p_lo] & 0x0Fu) ^ (col & d_mask[p_lo]));
404 output[s * 4 + k] = static_cast<u8>(hi | lo);
405 }
406 }
407}

References spreadA(), spreadB(), fl::W0, and fl::W1.

Referenced by fl::wave8Transpose_4_bf1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_8()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_8 ( const Wave8Byte lane_waves[8],
u8 output[8 *sizeof(Wave8Byte)] )

Transpose 8 lanes of Wave8Byte data into interleaved format.

Parameters
lane_wavesArray of 8 Wave8Byte structures
outputOutput buffer (64 bytes)

Spread-LUT transpose (#2533): ~1.90× faster than the unrolled naive on the ESP32-P4 (RV32) — 3356→1764 us/frame, bit-exact. See bit_spread_lut.hpp.

Definition at line 205 of file wave8.hpp.

206 {
207 for (int symbol_idx = 0; symbol_idx < 8; symbol_idx++) {
208 u8 l[8];
209 for (int lane = 0; lane < 8; lane++) {
210 l[lane] = lane_waves[lane].symbols[symbol_idx].data;
211 }
212 spread_transpose8_symbol(l, output + symbol_idx * 8);
213 }
214}

References spread_transpose8_symbol().

Referenced by fl::wave8Transpose_8(), and fl::wave8Transpose_8().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wave8_transpose_8_bf1()

FASTLED_FORCE_INLINE FL_IRAM FL_OPTIMIZE_FUNCTION void fl::detail::wave8_transpose_8_bf1 ( const u8 lanes[8],
u8 W0,
u8 W1,
u8 output[8 *sizeof(Wave8Byte)] )

BF1 for 8-lane Wave8 — same algebraic identity as 16-lane BF1.

Output: 8 symbols × 8 pulses × 1 byte = 64 bytes. Each pulse byte carries 8 lanes' bits at the corresponding pulse position. Uses spread_transpose8_symbol to compute the bit transpose in one call.

Definition at line 345 of file wave8.hpp.

347 {
348 u8 d_mask[8];
349 u8 m0_mask[8];
350 const u8 D_byte = W0 ^ W1;
351 for (int p = 0; p < 8; ++p) {
352 const int shift = 7 - p;
353 d_mask[p] = ((D_byte >> shift) & 1) ? 0xFFu : 0x00u;
354 m0_mask[p] = ((W0 >> shift) & 1) ? 0xFFu : 0x00u;
355 }
356 u8 cols[8];
357 spread_transpose8_symbol(lanes, cols);
358 for (int s = 0; s < 8; ++s) {
359 const u8 col = cols[s];
360 for (int p = 0; p < 8; ++p) {
361 output[s * 8 + p] = m0_mask[p] ^ (col & d_mask[p]);
362 }
363 }
364}

References spread_transpose8_symbol(), fl::W0, and fl::W1.

Referenced by fl::wave8Transpose_8_bf1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ kSpreadNibble

u32 fl::detail::kSpreadNibble[16]
constexpr
Initial value:
= {
0x00000000u, 0x01000000u, 0x00010000u, 0x01010000u,
0x00000100u, 0x01000100u, 0x00010100u, 0x01010100u,
0x00000001u, 0x01000001u, 0x00010001u, 0x01010001u,
0x00000101u, 0x01000101u, 0x00010101u, 0x01010101u,
}

kSpreadNibble[n] places the 4 bits of nibble n at bit 0 of 4 separate bytes: byte0 = bit3(n), byte1 = bit2(n), byte2 = bit1(n), byte3 = bit0(n).

A 16-entry literal table (C++11-valid, no constexpr loop, ~64 bytes, cache- resident). spreadA/spreadB only depend on one nibble each, so this one table serves both halves.

Definition at line 27 of file bit_spread_lut.hpp.

27 {
28 0x00000000u, 0x01000000u, 0x00010000u, 0x01010000u,
29 0x00000100u, 0x01000100u, 0x00010100u, 0x01010100u,
30 0x00000001u, 0x01000001u, 0x00010001u, 0x01010001u,
31 0x00000101u, 0x01000101u, 0x00010101u, 0x01010101u,
32};

Referenced by spreadA(), and spreadB().

◆ kTranspose2_4_LUT

u8 fl::detail::kTranspose2_4_LUT[4]
constexpr
Initial value:
= {
0x00,
0x01,
0x10,
0x11
}

Definition at line 33 of file wave8.hpp.

33 {
34 0x00, // 0b00 → no bits set
35 0x01, // 0b01 → bit at position 0 (pulse 1)
36 0x10, // 0b10 → bit at position 4 (pulse 0)
37 0x11 // 0b11 → bits at positions 0 and 4 (both pulses)
38};

◆ kTranspose4_16_LUT

u8 fl::detail::kTranspose4_16_LUT[16]
constexpr
Initial value:
= {0x00, 0x01, 0x04, 0x05, 0x10, 0x11,
0x14, 0x15, 0x40, 0x41, 0x44, 0x45,
0x50, 0x51, 0x54, 0x55}

Definition at line 26 of file wave8.hpp.

26 {0x00, 0x01, 0x04, 0x05, 0x10, 0x11,
27 0x14, 0x15, 0x40, 0x41, 0x44, 0x45,
28 0x50, 0x51, 0x54, 0x55};