Lumitronix_Iflex_Pro_Workshop
Library to interact with the iFlexPro
NeoEsp32I2sXMethod.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*-------------------------------------------------------------------------
4 LumitronixIFlex library helper functions for Esp32.
5 
6 Written by Michael C. Miller.
7 
8 I invest time and resources providing this open source code,
9 please support me by dontating (see https://github.com/Makuna)
10 
11 -------------------------------------------------------------------------
12 This file is part of the LUMITRONIX_iFlex_Workshop library.
13 
14 LumitronixIFlexBus is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as
16 published by the Free Software Foundation, either version 3 of
17 the License, or (at your option) any later version.
18 
19 LumitronixIFlexBus is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU Lesser General Public License for more details.
23 
24 You should have received a copy of the GNU Lesser General Public
25 License along with LumitronixIFlex. If not, see
26 <http://www.gnu.org/licenses/>.
27 -------------------------------------------------------------------------*/
28 
29 // ESP32C3/S3 I2S is not supported yet due to significant changes to interface
30 #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
31 
32 extern "C"
33 {
34 #include "Esp32_i2s.h"
35 }
36 
37 #pragma once
38 
39 // ESP32 Endian Map
40 // uint16_t
41 // 1234
42 // 3412
43 // uint32_t
44 // 12345678
45 // 78563412
46 // uint64_t
47 // 0123456789abcdef
48 // efcdab8967452301
49 
50 //
51 // true size of mux channel, 8 bit
52 //
53 class NeoEspI2sMuxBusSize8Bit
54 {
55 public:
56  NeoEspI2sMuxBusSize8Bit() {};
57 
58  const static size_t MuxBusDataSize = 1;
59 
60  static void EncodeIntoDma(uint8_t* dmaBuffer, const uint8_t* data, size_t sizeData, uint8_t muxId)
61  {
62 #if defined(CONFIG_IDF_TARGET_ESP32S2)
63  // 1234 - order
64  // 3412 = actual due to endianness
65  // 00000001
66  const uint32_t EncodedZeroBit = 0x00000100;
67  // 00010101
68  const uint32_t EncodedOneBit = 0x01000101;
69 #else
70  // 8 channel bits layout for DMA 32bit value
71  // note, right to left
72  // mux bus bit/id 76543210 76543210 76543210 76543210
73  // encode bit # 3 2 1 0
74  // value zero 0 0 0 1
75  // value one 0 1 1 1
76  //
77  // due to indianness between peripheral and cpu, bytes within the words are swapped in the const
78  // 1234 - order
79  // 3412 = actual due to endianness
80  // 00000001
81  const uint32_t EncodedZeroBit = 0x00010000;
82  // 00010101
83  const uint32_t EncodedOneBit = 0x01010001;
84 #endif
85 
86  uint32_t* pDma = reinterpret_cast<uint32_t*>(dmaBuffer);
87  const uint8_t* pEnd = data + sizeData;
88 
89  for (const uint8_t* pPixel = data; pPixel < pEnd; pPixel++)
90  {
91  uint8_t value = *pPixel;
92 
93  for (uint8_t bit = 0; bit < 8; bit++)
94  {
95  uint32_t dma = *(pDma);
96 
97  dma |= (((value & 0x80) ? EncodedOneBit : EncodedZeroBit) << (muxId));
98  *(pDma++) = dma;
99  value <<= 1;
100  }
101  }
102  }
103 };
104 
105 //
106 // true size of mux channel, 16 bit
107 //
108 class NeoEspI2sMuxBusSize16Bit
109 {
110 public:
111  NeoEspI2sMuxBusSize16Bit() {};
112 
113  const static size_t MuxBusDataSize = 2;
114 
115  static void EncodeIntoDma(uint8_t* dmaBuffer, const uint8_t* data, size_t sizeData, uint8_t muxId)
116  {
117 #if defined(CONFIG_IDF_TARGET_ESP32S2)
118  // 1234 5678 - order
119  // 3412 7856 = actual due to endianness
120  // not swap 0000000000000001
121  const uint64_t EncodedZeroBit64 = 0x0000000000010000;
122  // no swap 0000000100010001
123  const uint64_t EncodedOneBit64 = 0x0001000000010001;
124  // can be shifted by 8!
125  Fillx16(dmaBuffer,
126  data,
127  sizeData,
128  muxId,
129  EncodedZeroBit64,
130  EncodedOneBit64);
131 #else
132 
133  // 16 channel bits layout for DMA 64bit value
134  // note, right to left, destination is 32bit chunks
135  // due to indianness between peripheral and cpu,
136  // bytes within the words are swapped and words within dwords
137  // in the literal constants
138  // { } { }
139  // 0123 4567 89ab cdef - order of bytes in literal constant
140  // efcd ab89 6745 2301 - order of memory on ESP32 due to Endianness
141  // 6745 2301 efcd ab89 - 32bit dest means only map using 32bits so swap upper and lower
142  //
143  // Due to final bit locations, can't shift encoded one bit
144  // either left more than 7 or right more than 7 so we have to
145  // split the updates and use different encodings
146  if (muxId < 8)
147  {
148  // endian + dest swap 0000000000000001
149  const uint64_t EncodedZeroBit64 = 0x0000000001000000;
150  // endian + dest swap 0000000100010001
151  const uint64_t EncodedOneBit64 = 0x0100000001000100;
152  // cant be shifted by 8!
153  Fillx16(dmaBuffer,
154  data,
155  sizeData,
156  muxId,
157  EncodedZeroBit64,
158  EncodedOneBit64);
159  }
160  else
161  {
162  // endian + dest swap 0000000000000001
163  // then pre shift by 8 0000000000000100
164  const uint64_t EncodedZeroBit64 = 0x0000000000010000;
165  // endian + dest swap 0000000100010001
166  // then pre shift by 8 0000010001000100
167  const uint64_t EncodedOneBit64 = 0x0001000000010001;
168  Fillx16(dmaBuffer,
169  data,
170  sizeData,
171  muxId - 8, // preshifted
172  EncodedZeroBit64,
173  EncodedOneBit64);
174  }
175 #endif
176  }
177 
178 protected:
179  static void Fillx16(uint8_t* dmaBuffer,
180  const uint8_t* data,
181  size_t sizeData,
182  uint8_t muxShift,
183  const uint64_t EncodedZeroBit64,
184  const uint64_t EncodedOneBit64)
185  {
186  uint64_t* pDma64 = reinterpret_cast<uint64_t*>(dmaBuffer);
187  const uint8_t* pEnd = data + sizeData;
188 
189  for (const uint8_t* pPixel = data; pPixel < pEnd; pPixel++)
190  {
191  uint8_t value = *pPixel;
192 
193  for (uint8_t bit = 0; bit < 8; bit++)
194  {
195  uint64_t dma64 = *(pDma64);
196 
197  dma64 |= (((value & 0x80) ? EncodedOneBit64 : EncodedZeroBit64) << (muxShift));
198  *(pDma64++) = dma64;
199  value <<= 1;
200  }
201  }
202  }
203 };
204 
205 //
206 // tracks mux channels used and if updated
207 //
208 // T_FLAG - type used to store bit flags, UINT8_t for 8 channels, UINT16_t for 16
209 // T_MUXSIZE - true size of mux channel = NeoEspI2sMuxBusSize8Bit or NeoEspI2sMuxBusSize16Bit
210 //
211 template<typename T_FLAG, typename T_MUXSIZE> class NeoEspI2sMuxMap : public T_MUXSIZE
212 {
213 public:
214  const static uint8_t InvalidMuxId = -1;
215  const static size_t BusMaxCount = sizeof(T_FLAG) * 8;
216 
217  size_t MaxBusDataSize; // max size of stream data from any single mux bus
218  T_FLAG UpdateMap; // bitmap flags of mux buses to track update state
219  T_FLAG UpdateMapMask; // mask to used bits in s_UpdateMap
220  T_FLAG BusCount; // count of mux buses
221 
222  // as a static instance, all members get initialized to zero
223  // and the constructor is called at inconsistent time to other globals
224  // so its not useful to have or rely on,
225  // but without it presence they get zeroed far too late
226  NeoEspI2sMuxMap()
227  // //:
228  // //MaxBusDataSize(0),
229  // //UpdateMap(0),
230  // //UpdateMapMask(0),
231  // //BusCount(0)
232  {
233  }
234 
235  uint8_t RegisterNewMuxBus(const size_t dataSize)
236  {
237  // find first available bus id
238  uint8_t muxId = 0;
239  while (muxId < BusMaxCount)
240  {
241  T_FLAG muxIdField = (1 << muxId);
242  if ((UpdateMapMask & muxIdField) == 0)
243  {
244  // complete registration
245  BusCount++;
246  UpdateMapMask |= muxIdField;
247  if (dataSize > MaxBusDataSize)
248  {
249  MaxBusDataSize = dataSize;
250  }
251  break;
252  }
253  muxId++;
254  }
255  if (muxId == BusMaxCount)
256  {
257  log_e("exceded channel limit of %u on bus", BusMaxCount);
258  }
259  return muxId;
260  }
261 
262 
263  bool DeregisterMuxBus(uint8_t muxId)
264  {
265  T_FLAG muxIdField = (1 << muxId);
266  if (UpdateMapMask & muxIdField)
267  {
268  // complete deregistration
269  BusCount--;
270  UpdateMapMask &= ~muxIdField;
271  if (UpdateMapMask == 0)
272  {
273  return true;
274  }
275  }
276  return false;
277  }
278 
279  bool IsAllMuxBusesUpdated()
280  {
281  return (UpdateMap == UpdateMapMask);
282  }
283 
284  bool IsNoMuxBusesUpdate()
285  {
286  return (UpdateMap == 0);
287  }
288 
289  void MarkMuxBusUpdated(uint8_t muxId)
290  {
291  UpdateMap |= (1 << muxId);
292  }
293 
294  void ResetMuxBusesUpdated()
295  {
296  UpdateMap = 0;
297  }
298 
299  void Reset()
300  {
301  MaxBusDataSize = 0;
302  UpdateMap = 0;
303  UpdateMapMask = 0;
304  BusCount = 0;
305  }
306 };
307 
308 //
309 // Implementation of a Double Buffered version of a I2sContext
310 // Manages the underlying I2S details including the buffer(s)
311 // This creates a front buffer that can be filled while actively sending
312 // the back buffer, thus improving async operation of the i2s DMA.
313 // Note that the back buffer must be DMA memory, a limited resource, so
314 // the front buffer uses normal memory and copies rather than swap pointers
315 //
316 // T_MUXMAP - NeoEspI2sMuxMap - tracking class for mux state
317 //
318 template<typename T_MUXMAP> class NeoEspI2sDblBuffContext
319 {
320 public:
321  const static size_t DmaBitsPerPixelBit = 4;
322 
323  size_t I2sBufferSize; // total size of I2sBuffer
324  uint8_t* I2sBuffer; // holds the DMA buffer that is referenced by I2sBufDesc
325  uint8_t* I2sEditBuffer; // hold a editable buffer that is copied to I2sBuffer
326  T_MUXMAP MuxMap;
327 
328  // as a static instance, all members get initialized to zero
329  // and the constructor is called at inconsistent time to other globals
330  // so its not useful to have or rely on,
331  // but without it presence they get zeroed far too late
332  NeoEspI2sDblBuffContext()
333  // //:
334  // //I2sBufferSize(0),
335  // //I2sBuffer(nullptr),
336  // //I2sEditBuffer(nullptr),
337  // //MuxMap()
338  {
339  }
340 
341  void Construct(const uint8_t busNumber, uint32_t i2sSampleRate)
342  {
343  // construct only once on first time called
344  if (I2sBuffer == nullptr)
345  {
346  // MuxMap.MaxBusDataSize = max size in bytes of a single channel
347  // DmaBitsPerPixelBit = how many dma bits/byte are needed for each source (pixel) bit/byte
348  // T_MUXMAP::MuxBusDataSize = the true size of data for selected mux mode (not exposed size as i2s0 only supports 16bit mode)
349  I2sBufferSize = MuxMap.MaxBusDataSize * 8 * DmaBitsPerPixelBit * T_MUXMAP::MuxBusDataSize;
350 
351  // must have a 4 byte aligned buffer for i2s
352  uint32_t alignment = I2sBufferSize % 4;
353  if (alignment)
354  {
355  I2sBufferSize += 4 - alignment;
356  }
357 
358  size_t dmaBlockCount = (I2sBufferSize + I2S_DMA_MAX_DATA_LEN - 1) / I2S_DMA_MAX_DATA_LEN;
359 
360  I2sBuffer = static_cast<uint8_t*>(heap_caps_malloc(I2sBufferSize, MALLOC_CAP_DMA));
361  if (I2sBuffer == nullptr)
362  {
363  log_e("send buffer memory allocation failure (size %u)",
364  I2sBufferSize);
365  }
366  memset(I2sBuffer, 0x00, I2sBufferSize);
367 
368  I2sEditBuffer = static_cast<uint8_t*>(malloc(I2sBufferSize));
369  if (I2sEditBuffer == nullptr)
370  {
371  log_e("edit buffer memory allocation failure (size %u)",
372  I2sBufferSize);
373  }
374  memset(I2sEditBuffer, 0x00, I2sBufferSize);
375 
376  i2sInit(busNumber,
377  true,
378  T_MUXMAP::MuxBusDataSize,
379  i2sSampleRate,
380 #if defined(CONFIG_IDF_TARGET_ESP32S2)
381 // using these modes on ESP32S2 actually allows it to function
382 // in both x8 and x16
383  I2S_CHAN_STEREO,
384  I2S_FIFO_16BIT_DUAL,
385 #else
386 // but they won't work on ESP32 in parallel mode, but these will
387  I2S_CHAN_RIGHT_TO_LEFT,
388  I2S_FIFO_16BIT_SINGLE,
389 #endif
390  dmaBlockCount,
391  I2sBuffer,
392  I2sBufferSize);
393  }
394  }
395 
396  void Destruct(const uint8_t busNumber)
397  {
398  if (I2sBuffer == nullptr)
399  {
400  return;
401  }
402 
403  i2sSetPins(busNumber, -1, -1, -1, false);
404  i2sDeinit(busNumber);
405 
406  free(I2sEditBuffer);
407  heap_caps_free(I2sBuffer);
408 
409  I2sBufferSize = 0;
410  I2sBuffer = nullptr;
411  I2sEditBuffer = nullptr;
412 
413  MuxMap.Reset();
414  }
415 };
416 
417 //
418 // Implementation of the low level interface into i2s mux bus
419 //
420 // T_BUSCONTEXT - the context to use, currently only NeoEspI2sDblBuffContext but there is
421 // a plan to provide one that doesn't implement the front buffer but would be less
422 // async as it would have to wait until the last frame was completely sent before
423 // updating and new data
424 // T_BUS - the bus id, NeoEsp32I2sBusZero, NeoEsp32I2sBusOne
425 //
426 template<typename T_BUSCONTEXT, typename T_BUS> class NeoEsp32I2sMuxBus
427 {
428 public:
429  NeoEsp32I2sMuxBus() :
430  _muxId(s_context.MuxMap.InvalidMuxId)
431  {
432  }
433 
434  void RegisterNewMuxBus(size_t dataSize)
435  {
436  _muxId = s_context.MuxMap.RegisterNewMuxBus(dataSize);
437  }
438 
439  void Initialize(uint8_t pin, uint32_t i2sSampleRate, bool invert)
440  {
441  s_context.Construct(T_BUS::I2sBusNumber, i2sSampleRate);
442  i2sSetPins(T_BUS::I2sBusNumber, pin, _muxId, s_context.MuxMap.MuxBusDataSize, invert);
443  }
444 
445  void DeregisterMuxBus(uint8_t pin)
446  {
447  if (s_context.MuxMap.DeregisterMuxBus(_muxId))
448  {
449  s_context.Destruct(T_BUS::I2sBusNumber);
450  }
451 
452  // disconnect muxed pin
453  gpio_matrix_out(pin, 0x100, false, false);
454  pinMode(pin, INPUT);
455 
456  _muxId = s_context.MuxMap.InvalidMuxId;
457  }
458 
459  void StartWrite()
460  {
461  if (s_context.MuxMap.IsAllMuxBusesUpdated())
462  {
463  s_context.MuxMap.ResetMuxBusesUpdated();
464 
465  // wait for not actively sending data
466  while (!IsWriteDone())
467  {
468  yield();
469  }
470  // copy edit buffer to sending buffer
471  memcpy(s_context.I2sBuffer, s_context.I2sEditBuffer, s_context.I2sBufferSize);
472  i2sWrite(T_BUS::I2sBusNumber);
473  }
474  }
475 
476  bool IsWriteDone() const
477  {
478  return i2sWriteDone(T_BUS::I2sBusNumber);
479  }
480 
481  void FillBuffers(const uint8_t* data, size_t sizeData)
482  {
483  if (s_context.MuxMap.IsNoMuxBusesUpdate())
484  {
485  // clear all the data in preperation for each mux channel to add
486  memset(s_context.I2sEditBuffer, 0x00, s_context.I2sBufferSize);
487  }
488 
489  s_context.MuxMap.EncodeIntoDma(s_context.I2sEditBuffer,
490  data,
491  sizeData,
492  _muxId );
493 
494  s_context.MuxMap.MarkMuxBusUpdated(_muxId);
495  }
496 
497  void MarkUpdated()
498  {
499  s_context.MuxMap.MarkMuxBusUpdated(_muxId);
500  }
501 
502 private:
503  static T_BUSCONTEXT s_context;
504  uint8_t _muxId;
505 };
506 
507 template<typename T_BUSCONTEXT, typename T_BUS> T_BUSCONTEXT NeoEsp32I2sMuxBus<T_BUSCONTEXT, T_BUS>::s_context = T_BUSCONTEXT();
508 
509 //
510 // wrapping layer of the i2s mux bus as a NeoMethod
511 //
512 // T_SPEED - NeoEsp32I2sSpeed* (ex NeoEsp32I2sSpeedWs2812x) used to define output signal form
513 // T_BUS - NeoEsp32I2sMuxBus, the bus to use
514 // T_INVERT - NeoEsp32I2sNotInverted or NeoEsp32I2sInverted, will invert output signal
515 //
516 template<typename T_SPEED, typename T_BUS, typename T_INVERT> class NeoEsp32I2sXMethodBase
517 {
518 public:
519  typedef NeoNoSettings SettingsObject;
520 
521  NeoEsp32I2sXMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) :
522  _sizeData(pixelCount * elementSize + settingsSize),
523  _pin(pin),
524  _bus()
525  {
526  _bus.RegisterNewMuxBus(_sizeData + T_SPEED::ResetTimeUs / T_SPEED::ByteSendTimeUs);
527  }
528 
529  ~NeoEsp32I2sXMethodBase()
530  {
531  while (!_bus.IsWriteDone())
532  {
533  yield();
534  }
535 
536  _bus.DeregisterMuxBus(_pin);
537 
538  free(_data);
539  }
540 
541  bool IsReadyToUpdate() const
542  {
543  return _bus.IsWriteDone();
544  }
545 
546  void Initialize()
547  {
548  _bus.Initialize(_pin, T_SPEED::I2sSampleRate, T_INVERT::Inverted);
549 
550  _data = static_cast<uint8_t*>(malloc(_sizeData));
551  if (_data == nullptr)
552  {
553  log_e("front buffer memory allocation failure");
554  }
555  // data cleared later in Begin()
556  }
557 
558  void Update(bool)
559  {
560  _bus.FillBuffers(_data, _sizeData);
561  _bus.StartWrite(); // only triggers actual write after all mux busses have updated
562  }
563 
564  bool AlwaysUpdate()
565  {
566  // this method requires update to be called even if no changes to method buffer
567  // as edit buffer is always cleared and then copied to send buffer and all
568  // mux bus needs to included
569  return true;
570  }
571 
572  uint8_t* getData() const
573  {
574  return _data;
575  };
576 
577  size_t getDataSize() const
578  {
579  return _sizeData;
580  }
581 
582  void applySettings([[maybe_unused]] const SettingsObject& settings)
583  {
584  }
585 
586 private:
587  const size_t _sizeData; // Size of '_data' buffer
588  const uint8_t _pin; // output pin number
589 
590  T_BUS _bus; // holds instance for mux bus support
591  uint8_t* _data; // Holds LED color values
592 };
593 
594 #if defined(CONFIG_IDF_TARGET_ESP32S2)
595 
596 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint8_t, NeoEspI2sMuxBusSize8Bit>>, NeoEsp32I2sBusZero> NeoEsp32I2s0Mux8Bus;
597 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint16_t, NeoEspI2sMuxBusSize16Bit>>, NeoEsp32I2sBusZero> NeoEsp32I2s0Mux16Bus;
598 
599 #else
600 
601 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint8_t, NeoEspI2sMuxBusSize16Bit>>, NeoEsp32I2sBusZero> NeoEsp32I2s0Mux8Bus;
602 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint16_t, NeoEspI2sMuxBusSize16Bit>>, NeoEsp32I2sBusZero> NeoEsp32I2s0Mux16Bus;
603 
604 
605 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint8_t, NeoEspI2sMuxBusSize8Bit>>, NeoEsp32I2sBusOne> NeoEsp32I2s1Mux8Bus;
606 typedef NeoEsp32I2sMuxBus<NeoEspI2sDblBuffContext<NeoEspI2sMuxMap<uint16_t, NeoEspI2sMuxBusSize16Bit>>, NeoEsp32I2sBusOne> NeoEsp32I2s1Mux16Bus;
607 
608 #endif
609 
610 // NORMAL
611 //
612 
613 // I2s0x8
614 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Ws2812xMethod;
615 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Sk6812Method;
616 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Tm1814Method;
617 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Tm1829Method;
618 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Tm1914Method;
619 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8800KbpsMethod;
620 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8400KbpsMethod;
621 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Apa106Method;
622 
623 typedef NeoEsp32I2s0X8Ws2812xMethod NeoEsp32I2s0X8Ws2813Method;
624 typedef NeoEsp32I2s0X8Ws2812xMethod NeoEsp32I2s0X8Ws2812dMethod;
625 typedef NeoEsp32I2s0X8Ws2812xMethod NeoEsp32I2s0X8Ws2811Method;
626 typedef NeoEsp32I2s0X8Ws2812xMethod NeoEsp32I2s0X8Ws2816Method;
627 typedef NeoEsp32I2s0X8800KbpsMethod NeoEsp32I2s0X8Ws2812Method;
628 typedef NeoEsp32I2s0X8Sk6812Method NeoEsp32I2s0X8Lc8812Method;
629 
630 // I2s0x16
631 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Ws2812xMethod;
632 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Sk6812Method;
633 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Tm1814Method;
634 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Tm1829Method;
635 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Tm1914Method;
636 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16800KbpsMethod;
637 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16400KbpsMethod;
638 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Apa106Method;
639 
640 typedef NeoEsp32I2s0X16Ws2812xMethod NeoEsp32I2s0X16Ws2813Method;
641 typedef NeoEsp32I2s0X16Ws2812xMethod NeoEsp32I2s0X16Ws2812dMethod;
642 typedef NeoEsp32I2s0X16Ws2812xMethod NeoEsp32I2s0X16Ws2811Method;
643 typedef NeoEsp32I2s0X16Ws2812xMethod NeoEsp32I2s0X16Ws2816Method;
644 typedef NeoEsp32I2s0X16800KbpsMethod NeoEsp32I2s0X16Ws2812Method;
645 typedef NeoEsp32I2s0X16Sk6812Method NeoEsp32I2s0X16Lc8812Method;
646 
647 #if !defined(CONFIG_IDF_TARGET_ESP32S2)
648 
649 // I2s1x8
650 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Ws2812xMethod;
651 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Sk6812Method;
652 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Tm1814Method;
653 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Tm1829Method;
654 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Tm1914Method;
655 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8800KbpsMethod;
656 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8400KbpsMethod;
657 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Apa106Method;
658 
659 typedef NeoEsp32I2s1X8Ws2812xMethod NeoEsp32I2s1X8Ws2813Method;
660 typedef NeoEsp32I2s1X8Ws2812xMethod NeoEsp32I2s1X8Ws2812dMethod;
661 typedef NeoEsp32I2s1X8Ws2812xMethod NeoEsp32I2s1X8Ws2811Method;
662 typedef NeoEsp32I2s1X8Ws2812xMethod NeoEsp32I2s1X8Ws2816Method;
663 typedef NeoEsp32I2s1X8800KbpsMethod NeoEsp32I2s1X8Ws2812Method;
664 typedef NeoEsp32I2s1X8Sk6812Method NeoEsp32I2s1X8Lc8812Method;
665 
666 // I2s1x16
667 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Ws2812xMethod;
668 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Sk6812Method;
669 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Tm1814Method;
670 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Tm1829Method;
671 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Tm1914Method;
672 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16800KbpsMethod;
673 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16400KbpsMethod;
674 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Apa106Method;
675 
676 typedef NeoEsp32I2s1X16Ws2812xMethod NeoEsp32I2s1X16Ws2813Method;
677 typedef NeoEsp32I2s1X16Ws2812xMethod NeoEsp32I2s1X16Ws2812dMethod;
678 typedef NeoEsp32I2s1X16Ws2812xMethod NeoEsp32I2s1X16Ws2811Method;
679 typedef NeoEsp32I2s1X16Ws2812xMethod NeoEsp32I2s1X16Ws2816Method;
680 typedef NeoEsp32I2s1X16800KbpsMethod NeoEsp32I2s1X16Ws2812Method;
681 typedef NeoEsp32I2s1X16Sk6812Method NeoEsp32I2s1X16Lc8812Method;
682 
683 
684 #endif // !defined(CONFIG_IDF_TARGET_ESP32S2)
685 
686 // INVERTED
687 //
688 // I2s0x8 INVERTED
689 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Ws2812xInvertedMethod;
690 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Sk6812InvertedMethod;
691 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Tm1814InvertedMethod;
692 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Tm1829InvertedMethod;
693 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X8Tm1914InvertedMethod;
694 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8800KbpsInvertedMethod;
695 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8400KbpsInvertedMethod;
696 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s0Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X8Apa106InvertedMethod;
697 
698 typedef NeoEsp32I2s0X8Ws2812xInvertedMethod NeoEsp32I2s0X8Ws2813InvertedMethod;
699 typedef NeoEsp32I2s0X8Ws2812xInvertedMethod NeoEsp32I2s0X8Ws2812xInvertedMethod;
700 typedef NeoEsp32I2s0X8Ws2812xInvertedMethod NeoEsp32I2s0X8Ws2811InvertedMethod;
701 typedef NeoEsp32I2s0X8Ws2812xInvertedMethod NeoEsp32I2s0X8Ws2816InvertedMethod;
702 typedef NeoEsp32I2s0X8800KbpsInvertedMethod NeoEsp32I2s0X8Ws2812InvertedMethod;
703 typedef NeoEsp32I2s0X8Sk6812InvertedMethod NeoEsp32I2s0X8Lc8812InvertedMethod;
704 
705 
706 // I2s0x16 INVERTED
707 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Ws2812xInvertedMethod;
708 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Sk6812InvertedMethod;
709 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Tm1814InvertedMethod;
710 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Tm1829InvertedMethod;
711 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s0X16Tm1914InvertedMethod;
712 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16800KbpsInvertedMethod;
713 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16400KbpsInvertedMethod;
714 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s0Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s0X16Apa106InvertedMethod;
715 
716 typedef NeoEsp32I2s0X16Ws2812xInvertedMethod NeoEsp32I2s0X16Ws2813InvertedMethod;
717 typedef NeoEsp32I2s0X16Ws2812xInvertedMethod NeoEsp32I2s0X16Ws2812xInvertedMethod;
718 typedef NeoEsp32I2s0X16Ws2812xInvertedMethod NeoEsp32I2s0X16Ws2811InvertedMethod;
719 typedef NeoEsp32I2s0X16Ws2812xInvertedMethod NeoEsp32I2s0X16Ws2816InvertedMethod;
720 typedef NeoEsp32I2s0X16800KbpsInvertedMethod NeoEsp32I2s0X16Ws2812InvertedMethod;
721 typedef NeoEsp32I2s0X16Sk6812InvertedMethod NeoEsp32I2s0X16Lc8812InvertedMethod;
722 
723 #if !defined(CONFIG_IDF_TARGET_ESP32S2)
724 
725 // I2s1x8 INVERTED
726 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Ws2812xInvertedMethod;
727 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Sk6812InvertedMethod;
728 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Tm1814InvertedMethod;
729 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Tm1829InvertedMethod;
730 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X8Tm1914InvertedMethod;
731 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8800KbpsInvertedMethod;
732 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8400KbpsInvertedMethod;
733 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s1Mux8Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X8Apa106InvertedMethod;
734 
735 typedef NeoEsp32I2s1X8Ws2812xInvertedMethod NeoEsp32I2s1X8Ws2813InvertedMethod;
736 typedef NeoEsp32I2s1X8Ws2812xInvertedMethod NeoEsp32I2s1X8Ws2812xInvertedMethod;
737 typedef NeoEsp32I2s1X8Ws2812xInvertedMethod NeoEsp32I2s1X8Ws2811InvertedMethod;
738 typedef NeoEsp32I2s1X8Ws2812xInvertedMethod NeoEsp32I2s1X8Ws2816InvertedMethod;
739 typedef NeoEsp32I2s1X8800KbpsInvertedMethod NeoEsp32I2s1X8Ws2812InvertedMethod;
740 typedef NeoEsp32I2s1X8Sk6812InvertedMethod NeoEsp32I2s1X8Lc8812InvertedMethod;
741 
742 // I2s1x16 INVERTED
743 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedWs2812x, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Ws2812xInvertedMethod;
744 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedSk6812, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Sk6812InvertedMethod;
745 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1814, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Tm1814InvertedMethod;
746 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1829, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Tm1829InvertedMethod;
747 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedTm1914, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sNotInverted> NeoEsp32I2s1X16Tm1914InvertedMethod;
748 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed800Kbps, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16800KbpsInvertedMethod;
749 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeed400Kbps, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16400KbpsInvertedMethod;
750 typedef NeoEsp32I2sXMethodBase<NeoEsp32I2sSpeedApa106, NeoEsp32I2s1Mux16Bus, NeoEsp32I2sInverted> NeoEsp32I2s1X16Apa106InvertedMethod;
751 
752 typedef NeoEsp32I2s1X16Ws2812xInvertedMethod NeoEsp32I2s1X16Ws2813InvertedMethod;
753 typedef NeoEsp32I2s1X16Ws2812xInvertedMethod NeoEsp32I2s1X16Ws2812xInvertedMethod;
754 typedef NeoEsp32I2s1X16Ws2812xInvertedMethod NeoEsp32I2s1X16Ws2811InvertedMethod;
755 typedef NeoEsp32I2s1X16Ws2812xInvertedMethod NeoEsp32I2s1X16Ws2816InvertedMethod;
756 typedef NeoEsp32I2s1X16800KbpsInvertedMethod NeoEsp32I2s1X16Ws2812InvertedMethod;
757 typedef NeoEsp32I2s1X16Sk6812InvertedMethod NeoEsp32I2s1X16Lc8812InvertedMethod;
758 
759 #endif // !defined(CONFIG_IDF_TARGET_ESP32S2)
760 
761 #endif // defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
Definition: NeoSettings.h:29