mirror of https://github.com/arendst/Tasmota.git
Merge pull request #11241 from s-hadinger/fix_ws2812_esp32
Fix WS2812 ESP32
This commit is contained in:
commit
a1e2470338
|
@ -123,6 +123,113 @@ void (* const Ws2812Command[])(void) PROGMEM = {
|
|||
|
||||
#endif // No USE_WS2812_DMA
|
||||
|
||||
#ifdef ESP32
|
||||
//
|
||||
// Below is a quick work-around to ESP32 gcc that prevents templated methods to be in IRAM unless explicitly marked per specialization
|
||||
// It will work only for the default WS2812 (800KHz) and inverted and non-inverted
|
||||
//
|
||||
template <>
|
||||
void IRAM_ATTR NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinset>::send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
||||
{
|
||||
const uint32_t pinRegister = _BV(pin);
|
||||
uint8_t mask = 0x80;
|
||||
uint8_t subpix = *pixels++;
|
||||
uint32_t cyclesStart = 0; // trigger emediately
|
||||
uint32_t cyclesNext = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// do the checks here while we are waiting on time to pass
|
||||
uint32_t cyclesBit = NeoEspSpeed800Mhz::T0H;
|
||||
if (subpix & mask)
|
||||
{
|
||||
cyclesBit = NeoEspSpeed800Mhz::T1H;
|
||||
}
|
||||
|
||||
// after we have done as much work as needed for this next bit
|
||||
// now wait for the HIGH
|
||||
while (((cyclesStart = getCycleCount()) - cyclesNext) < NeoEspSpeed800Mhz::Period);
|
||||
|
||||
// set pin state
|
||||
NeoEspPinset::setPin(pinRegister);
|
||||
|
||||
// wait for the LOW
|
||||
while ((getCycleCount() - cyclesStart) < cyclesBit);
|
||||
|
||||
// reset pin start
|
||||
NeoEspPinset::resetPin(pinRegister);
|
||||
|
||||
cyclesNext = cyclesStart;
|
||||
|
||||
// next bit
|
||||
mask >>= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
// no more bits to send in this byte
|
||||
// check for another byte
|
||||
if (pixels >= end)
|
||||
{
|
||||
// no more bytes to send so stop
|
||||
break;
|
||||
}
|
||||
// reset mask to first bit and get the next byte
|
||||
mask = 0x80;
|
||||
subpix = *pixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <>
|
||||
void IRAM_ATTR NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinsetInverted>::send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
||||
{
|
||||
const uint32_t pinRegister = _BV(pin);
|
||||
uint8_t mask = 0x80;
|
||||
uint8_t subpix = *pixels++;
|
||||
uint32_t cyclesStart = 0; // trigger emediately
|
||||
uint32_t cyclesNext = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// do the checks here while we are waiting on time to pass
|
||||
uint32_t cyclesBit = NeoEspSpeed800Mhz::T0H;
|
||||
if (subpix & mask)
|
||||
{
|
||||
cyclesBit = NeoEspSpeed800Mhz::T1H;
|
||||
}
|
||||
|
||||
// after we have done as much work as needed for this next bit
|
||||
// now wait for the HIGH
|
||||
while (((cyclesStart = getCycleCount()) - cyclesNext) < NeoEspSpeed800Mhz::Period);
|
||||
|
||||
// set pin state
|
||||
NeoEspPinsetInverted::setPin(pinRegister);
|
||||
|
||||
// wait for the LOW
|
||||
while ((getCycleCount() - cyclesStart) < cyclesBit);
|
||||
|
||||
// reset pin start
|
||||
NeoEspPinsetInverted::resetPin(pinRegister);
|
||||
|
||||
cyclesNext = cyclesStart;
|
||||
|
||||
// next bit
|
||||
mask >>= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
// no more bits to send in this byte
|
||||
// check for another byte
|
||||
if (pixels >= end)
|
||||
{
|
||||
// no more bytes to send so stop
|
||||
break;
|
||||
}
|
||||
// reset mask to first bit and get the next byte
|
||||
mask = 0x80;
|
||||
subpix = *pixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ESP32
|
||||
|
||||
NeoPixelBus<selectedNeoFeatureType, selectedNeoSpeedType> *strip = nullptr;
|
||||
|
||||
struct WsColor {
|
||||
|
|
Loading…
Reference in New Issue