29 #ifdef ARDUINO_ARCH_ESP8266
33 class NeoEsp8266I2sDmx512SpeedBase
37 static const uint32_t I2sClockDivisor = 20;
38 static const uint32_t I2sBaseClockDivisor = 32;
39 static const uint32_t ByteSendTimeUs = 44;
40 static const uint32_t BreakMabUs = 96;
41 static const size_t BreakMabSize = 4;
42 static const uint32_t MtbpUs = 11;
43 static const size_t MtbpSize = 1;
45 static const size_t HeaderSize = 1;
48 class NeoEsp8266I2sDmx512Speed :
public NeoEsp8266I2sDmx512SpeedBase
51 static const uint8_t MtbpLevel = 0x1;
52 static const uint8_t StartBit = 0b00000000;
53 static const uint8_t StopBits = 0b00000011;
54 static const uint32_t Break = 0x00000000;
55 static const uint32_t BreakMab = 0x00000007;
57 static uint8_t Convert(uint8_t value)
64 class NeoEsp8266I2sDmx512InvertedSpeed :
public NeoEsp8266I2sDmx512SpeedBase
67 static const uint8_t MtbpLevel = 0x00;
68 static const uint8_t StartBit = 0b00000001;
69 static const uint8_t StopBits = 0b00000000;
70 static const uint32_t Break = 0xffffffff;
71 static const uint32_t BreakMab = 0xfffffff8;
73 static uint8_t Convert(uint8_t value)
81 class NeoEsp8266I2sWs2821SpeedBase
85 static const uint32_t I2sClockDivisor = 27;
86 static const uint32_t I2sBaseClockDivisor = 8;
87 static const uint32_t ByteSendTimeUs = 15;
88 static const uint32_t BreakMabUs = 92;
89 static const size_t BreakMabSize = 12;
90 static const uint32_t MtbpUs = 88;
91 static const size_t MtbpSize = 9;
94 static const size_t HeaderSize = 1;
97 class NeoEsp8266I2sWs2821Speed :
public NeoEsp8266I2sWs2821SpeedBase
100 static const uint8_t MtbpLevel = 0x1;
101 static const uint8_t StartBit = 0b00000000;
102 static const uint8_t StopBits = 0b00000011;
103 static const uint32_t Break = 0x00000000;
104 static const uint32_t BreakMab = 0x00000007;
106 static uint8_t Convert(uint8_t value)
113 class NeoEsp8266I2sWs2821InvertedSpeed :
public NeoEsp8266I2sWs2821SpeedBase
116 static const uint8_t MtbpLevel = 0x00;
117 static const uint8_t StartBit = 0b00000001;
118 static const uint8_t StopBits = 0b00000000;
119 static const uint32_t Break = 0xffffffff;
120 static const uint32_t BreakMab = 0xfffffff8;
122 static uint8_t Convert(uint8_t value)
129 template<
typename T_SPEED>
class NeoEsp8266I2sDmx512MethodBase : NeoEsp8266I2sMethodCore
134 NeoEsp8266I2sDmx512MethodBase(uint16_t pixelCount,
size_t elementSize,
size_t settingsSize) :
135 _sizeData(pixelCount * elementSize + settingsSize + T_SPEED::HeaderSize)
137 size_t dmaPixelBits = I2sBitsPerPixelBytes * elementSize;
138 size_t dmaSettingsBits = I2sBitsPerPixelBytes * (settingsSize + T_SPEED::HeaderSize);
141 size_t i2sBufferSize = (pixelCount * dmaPixelBits + dmaSettingsBits + 4) / 8;
143 i2sBufferSize = i2sBufferSize + T_SPEED::BreakMabSize;
149 size_t i2sResetSize =
NeoUtil::RoundUp(T_SPEED::MtbpSize, c_I2sByteBoundarySize);
152 size_t is2BufMaxBlockSize = (c_maxDmaBlockSize / c_I2sByteBoundarySize) * c_I2sByteBoundarySize;
154 _data =
static_cast<uint8_t*
>(malloc(_sizeData));
156 memset(_data, 0x00, 1);
158 AllocateI2s(i2sBufferSize, i2sResetSize, is2BufMaxBlockSize, T_SPEED::MtbpLevel);
161 NeoEsp8266I2sDmx512MethodBase([[maybe_unused]] uint8_t pin, uint16_t pixelCount,
size_t elementSize,
size_t settingsSize) :
162 NeoEsp8266I2sDmx512MethodBase(pixelCount, elementSize, settingsSize)
166 ~NeoEsp8266I2sDmx512MethodBase()
169 while (!IsReadyToUpdate())
177 uint32_t time = micros();
178 while ((micros() - time) < ((getPixelTime() + T_SPEED::MtbpUs) * waits))
188 bool IsReadyToUpdate()
const
195 InitializeI2s(T_SPEED::I2sClockDivisor, T_SPEED::I2sBaseClockDivisor);
198 void IRAM_ATTR Update(
bool)
201 while (!IsReadyToUpdate())
216 uint8_t* getData()
const
218 return _data + T_SPEED::HeaderSize;
221 size_t getDataSize()
const
223 return _sizeData - T_SPEED::HeaderSize;
226 void applySettings([[maybe_unused]]
const SettingsObject& settings)
232 static const uint16_t I2sBitsPerPixelBytes = 11;
234 const size_t _sizeData;
240 static void Encoder(
const uint8_t* pSrc,
const uint8_t* pSrcEnd,
241 uint32_t* pOutput,
const uint32_t* pOutputEnd)
243 static const uint32_t Mtbp = 0xffffffff * T_SPEED::MtbpLevel;
244 const uint8_t* pData = pSrc;
246 int8_t outputBit = 32;
250 while (pData < pSrcEnd)
252 uint8_t data = T_SPEED::Convert( *(pData++) );
258 output |= T_SPEED::StartBit << outputBit;
261 output |= data << outputBit;
264 output |= T_SPEED::StopBits << outputBit;
272 *(pOutput++) = output;
277 output |= (T_SPEED::StartBit << outputBit);
282 output |= data >> (8 - outputBit);
284 *(pOutput++) = output;
289 output |= data << outputBit;
294 output |= T_SPEED::StopBits >> (2 - outputBit);
296 *(pOutput++) = output;
301 output |= T_SPEED::StopBits << outputBit;
307 output |= Mtbp >> (32 - outputBit);
308 *(pOutput++) = output;
311 while (pOutput < pOutputEnd)
320 uint32_t* pDma32 =
reinterpret_cast<uint32_t*
>(_i2sBuffer);
321 const uint32_t* pDma32End =
reinterpret_cast<uint32_t*
>(_i2sBuffer + _i2sBufferSize);
324 for (
size_t count = 1;
325 count < (T_SPEED::BreakMabSize/
sizeof(T_SPEED::Break));
328 *(pDma32++) = T_SPEED::Break;
331 *(pDma32++) = T_SPEED::BreakMab;
333 Encoder(_data, _data + _sizeData, pDma32, pDma32End);
336 uint32_t getPixelTime()
const
338 return (T_SPEED::ByteSendTimeUs * this->_sizeData);
345 typedef NeoEsp8266I2sDmx512MethodBase<NeoEsp8266I2sDmx512Speed> NeoEsp8266Dmx512Method;
346 typedef NeoEsp8266I2sDmx512MethodBase<NeoEsp8266I2sWs2821Speed> NeoEsp8266Ws2821Method;
349 typedef NeoEsp8266I2sDmx512MethodBase<NeoEsp8266I2sDmx512InvertedSpeed> NeoEsp8266Dmx512InvertedMethod;
350 typedef NeoEsp8266I2sDmx512MethodBase<NeoEsp8266I2sWs2821InvertedSpeed> NeoEsp8266Ws2821InvertedMethod;
Definition: NeoSettings.h:29
static size_t RoundUp(size_t numToRound, size_t multiple)
Definition: NeoUtil.h:62
static uint8_t Reverse8Bits(uint8_t n)
Definition: NeoUtil.h:57