Merge pull request #11241 from s-hadinger/fix_ws2812_esp32

Fix WS2812 ESP32
This commit is contained in:
s-hadinger 2021-03-06 19:01:20 +01:00 committed by GitHub
commit a1e2470338
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 107 additions and 0 deletions

View File

@ -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 {