mirror of https://github.com/arendst/Tasmota.git
ESP32 better fix for IRAM Bit Bang
This commit is contained in:
parent
a1e2470338
commit
a10564b5c5
|
@ -0,0 +1,115 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixel library helper functions for Esp8266 and Esp32
|
||||||
|
|
||||||
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
|
I invest time and resources providing this open source code,
|
||||||
|
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
This file is part of the Makuna/NeoPixelBus library.
|
||||||
|
|
||||||
|
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
NeoPixelBus is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with NeoPixel. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "NeoEspBitBangMethod.h"
|
||||||
|
|
||||||
|
static inline uint32_t getCycleCount(void)
|
||||||
|
{
|
||||||
|
uint32_t ccount;
|
||||||
|
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||||
|
return ccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR NeoEspBitBangBase_send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin, uint32_t t0h, uint32_t t1h, uint32_t period, uint8_t IdleLevel)
|
||||||
|
{
|
||||||
|
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 = t0h;
|
||||||
|
if (subpix & mask)
|
||||||
|
{
|
||||||
|
cyclesBit = t1h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// after we have done as much work as needed for this next bit
|
||||||
|
// now wait for the HIGH
|
||||||
|
while (((cyclesStart = getCycleCount()) - cyclesNext) < period);
|
||||||
|
|
||||||
|
// set pin state
|
||||||
|
if (IdleLevel == LOW) {
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
GPIO.out_w1ts = pinRegister;
|
||||||
|
#else
|
||||||
|
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
GPIO.out_w1tc = pinRegister;
|
||||||
|
#else
|
||||||
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// T_PINSET::setPin(pinRegister);
|
||||||
|
|
||||||
|
// wait for the LOW
|
||||||
|
while ((getCycleCount() - cyclesStart) < cyclesBit);
|
||||||
|
|
||||||
|
// reset pin start
|
||||||
|
if (IdleLevel == LOW) {
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
GPIO.out_w1tc = pinRegister;
|
||||||
|
#else
|
||||||
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
GPIO.out_w1ts = pinRegister;
|
||||||
|
#else
|
||||||
|
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// T_PINSET::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
|
|
@ -55,6 +55,14 @@ public:
|
||||||
const static uint32_t Period = (F_CPU / 800000 - CYCLES_LOOPTEST); // 1.25us per bit
|
const static uint32_t Period = (F_CPU / 800000 - CYCLES_LOOPTEST); // 1.25us per bit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NeoEspSpeedTm1829
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const static uint32_t T0H = (F_CPU / 3333333 - CYCLES_LOOPTEST); // 0.3us
|
||||||
|
const static uint32_t T1H = (F_CPU / 1250000 - CYCLES_LOOPTEST); // 0.8us
|
||||||
|
const static uint32_t Period = (F_CPU / 800000 - CYCLES_LOOPTEST); // 1.25us per bit
|
||||||
|
};
|
||||||
|
|
||||||
class NeoEspSpeed800Mhz
|
class NeoEspSpeed800Mhz
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -83,109 +91,22 @@ class NeoEspPinset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const static uint8_t IdleLevel = LOW;
|
const static uint8_t IdleLevel = LOW;
|
||||||
|
|
||||||
inline static void setPin(const uint32_t pinRegister)
|
|
||||||
{
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
GPIO.out_w1ts = pinRegister;
|
|
||||||
#else
|
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void resetPin(const uint32_t pinRegister)
|
|
||||||
{
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
GPIO.out_w1tc = pinRegister;
|
|
||||||
#else
|
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NeoEspPinsetInverted
|
class NeoEspPinsetInverted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const static uint8_t IdleLevel = HIGH;
|
const static uint8_t IdleLevel = HIGH;
|
||||||
|
|
||||||
inline static void setPin(const uint32_t pinRegister)
|
|
||||||
{
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
GPIO.out_w1tc = pinRegister;
|
|
||||||
#else
|
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void resetPin(const uint32_t pinRegister)
|
|
||||||
{
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
GPIO.out_w1ts = pinRegister;
|
|
||||||
#else
|
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void NeoEspBitBangBase_send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin, uint32_t t0h, uint32_t t1h, uint32_t period, uint8_t IdleLevel);
|
||||||
|
|
||||||
template<typename T_SPEED, typename T_PINSET> class NeoEspBitBangBase
|
template<typename T_SPEED, typename T_PINSET> class NeoEspBitBangBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
__attribute__((noinline)) static void ICACHE_RAM_ATTR send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
static void send_pixels(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
||||||
{
|
{
|
||||||
const uint32_t pinRegister = _BV(pin);
|
NeoEspBitBangBase_send_pixels(pixels, end, pin, T_SPEED::T0H, T_SPEED::T1H, T_SPEED::Period, T_PINSET::IdleLevel);
|
||||||
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 = T_SPEED::T0H;
|
|
||||||
if (subpix & mask)
|
|
||||||
{
|
|
||||||
cyclesBit = T_SPEED::T1H;
|
|
||||||
}
|
|
||||||
|
|
||||||
// after we have done as much work as needed for this next bit
|
|
||||||
// now wait for the HIGH
|
|
||||||
while (((cyclesStart = getCycleCount()) - cyclesNext) < T_SPEED::Period);
|
|
||||||
|
|
||||||
// set pin state
|
|
||||||
T_PINSET::setPin(pinRegister);
|
|
||||||
|
|
||||||
// wait for the LOW
|
|
||||||
while ((getCycleCount() - cyclesStart) < cyclesBit);
|
|
||||||
|
|
||||||
// reset pin start
|
|
||||||
T_PINSET::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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static inline uint32_t getCycleCount(void)
|
|
||||||
{
|
|
||||||
uint32_t ccount;
|
|
||||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
|
||||||
return ccount;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,6 +135,13 @@ public:
|
||||||
static const uint32_t ResetTimeUs = 200;
|
static const uint32_t ResetTimeUs = 200;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// normal is inverted signal
|
||||||
|
class NeoEspBitBangSpeedTm1829 : public NeoEspBitBangBase<NeoEspSpeedTm1829, NeoEspPinsetInverted>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t ResetTimeUs = 200;
|
||||||
|
};
|
||||||
|
|
||||||
class NeoEspBitBangSpeed800Kbps : public NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinset>
|
class NeoEspBitBangSpeed800Kbps : public NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinset>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -257,6 +185,13 @@ public:
|
||||||
static const uint32_t ResetTimeUs = 200;
|
static const uint32_t ResetTimeUs = 200;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// normal is inverted signal, so inverted is normal
|
||||||
|
class NeoEspBitBangInvertedSpeedTm1829 : public NeoEspBitBangBase<NeoEspSpeedTm1829, NeoEspPinset>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t ResetTimeUs = 200;
|
||||||
|
};
|
||||||
|
|
||||||
class NeoEspBitBangInvertedSpeed800Kbps : public NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinsetInverted>
|
class NeoEspBitBangInvertedSpeed800Kbps : public NeoEspBitBangBase<NeoEspSpeed800Mhz, NeoEspPinsetInverted>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -278,6 +213,8 @@ public:
|
||||||
template<typename T_SPEED, typename T_PINSET> class NeoEspBitBangMethodBase
|
template<typename T_SPEED, typename T_PINSET> class NeoEspBitBangMethodBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef NeoNoSettings SettingsObject;
|
||||||
|
|
||||||
NeoEspBitBangMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) :
|
NeoEspBitBangMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) :
|
||||||
_sizeData(pixelCount * elementSize + settingsSize),
|
_sizeData(pixelCount * elementSize + settingsSize),
|
||||||
_pin(pin)
|
_pin(pin)
|
||||||
|
@ -354,6 +291,10 @@ public:
|
||||||
return _sizeData;
|
return _sizeData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void applySettings(const SettingsObject& settings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const size_t _sizeData; // Size of '_data' buffer below
|
const size_t _sizeData; // Size of '_data' buffer below
|
||||||
const uint8_t _pin; // output pin number
|
const uint8_t _pin; // output pin number
|
||||||
|
@ -369,6 +310,7 @@ typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2811, NeoEspPinset> NeoEsp32
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2812x, NeoEspPinset> NeoEsp32BitBangWs2812xMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2812x, NeoEspPinset> NeoEsp32BitBangWs2812xMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedSk6812, NeoEspPinset> NeoEsp32BitBangSk6812Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedSk6812, NeoEspPinset> NeoEsp32BitBangSk6812Method;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1814, NeoEspPinsetInverted> NeoEsp32BitBangTm1814Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1814, NeoEspPinsetInverted> NeoEsp32BitBangTm1814Method;
|
||||||
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1829, NeoEspPinsetInverted> NeoEsp32BitBangTm1829Method;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps, NeoEspPinset> NeoEsp32BitBang800KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps, NeoEspPinset> NeoEsp32BitBang800KbpsMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps, NeoEspPinset> NeoEsp32BitBang400KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps, NeoEspPinset> NeoEsp32BitBang400KbpsMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedApa106, NeoEspPinset> NeoEsp32BitBangApa106Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedApa106, NeoEspPinset> NeoEsp32BitBangApa106Method;
|
||||||
|
@ -381,6 +323,7 @@ typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2811, NeoEspPinsetIn
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2812x, NeoEspPinsetInverted> NeoEsp32BitBangWs2812xInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2812x, NeoEspPinsetInverted> NeoEsp32BitBangWs2812xInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedSk6812, NeoEspPinsetInverted> NeoEsp32BitBangSk6812InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedSk6812, NeoEspPinsetInverted> NeoEsp32BitBangSk6812InvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1814, NeoEspPinset> NeoEsp32BitBangTm1814InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1814, NeoEspPinset> NeoEsp32BitBangTm1814InvertedMethod;
|
||||||
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1829, NeoEspPinset> NeoEsp32BitBangTm1829InvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed800Kbps, NeoEspPinsetInverted> NeoEsp32BitBang800KbpsInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed800Kbps, NeoEspPinsetInverted> NeoEsp32BitBang800KbpsInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed400Kbps, NeoEspPinsetInverted> NeoEsp32BitBang400KbpsInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed400Kbps, NeoEspPinsetInverted> NeoEsp32BitBang400KbpsInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedApa106, NeoEspPinsetInverted> NeoEsp32BitBangApa106InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedApa106, NeoEspPinsetInverted> NeoEsp32BitBangApa106InvertedMethod;
|
||||||
|
@ -395,6 +338,7 @@ typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2811, NeoEspPinset> NeoEsp82
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2812x, NeoEspPinset> NeoEsp8266BitBangWs2812xMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedWs2812x, NeoEspPinset> NeoEsp8266BitBangWs2812xMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedSk6812, NeoEspPinset> NeoEsp8266BitBangSk6812Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedSk6812, NeoEspPinset> NeoEsp8266BitBangSk6812Method;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1814, NeoEspPinsetInverted> NeoEsp8266BitBangTm1814Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1814, NeoEspPinsetInverted> NeoEsp8266BitBangTm1814Method;
|
||||||
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedTm1829, NeoEspPinsetInverted> NeoEsp8266BitBangTm1829Method;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps, NeoEspPinset> NeoEsp8266BitBang800KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps, NeoEspPinset> NeoEsp8266BitBang800KbpsMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps, NeoEspPinset> NeoEsp8266BitBang400KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps, NeoEspPinset> NeoEsp8266BitBang400KbpsMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedApa106, NeoEspPinset> NeoEsp8266BitBangApa106Method;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedApa106, NeoEspPinset> NeoEsp8266BitBangApa106Method;
|
||||||
|
@ -407,6 +351,7 @@ typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2811, NeoEspPinsetIn
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2812x, NeoEspPinsetInverted> NeoEsp8266BitBangWs2812xInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedWs2812x, NeoEspPinsetInverted> NeoEsp8266BitBangWs2812xInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedSk6812, NeoEspPinsetInverted> NeoEsp8266BitBangSk6812InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedSk6812, NeoEspPinsetInverted> NeoEsp8266BitBangSk6812InvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1814, NeoEspPinset> NeoEsp8266BitBangTm1814InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1814, NeoEspPinset> NeoEsp8266BitBangTm1814InvertedMethod;
|
||||||
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedTm1829, NeoEspPinset> NeoEsp8266BitBangTm1829InvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed800Kbps, NeoEspPinsetInverted> NeoEsp8266BitBang800KbpsInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed800Kbps, NeoEspPinsetInverted> NeoEsp8266BitBang800KbpsInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed400Kbps, NeoEspPinsetInverted> NeoEsp8266BitBang400KbpsInvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeed400Kbps, NeoEspPinsetInverted> NeoEsp8266BitBang400KbpsInvertedMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedApa106, NeoEspPinsetInverted> NeoEsp8266BitBangApa106InvertedMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangInvertedSpeedApa106, NeoEspPinsetInverted> NeoEsp8266BitBangApa106InvertedMethod;
|
||||||
|
|
|
@ -123,113 +123,6 @@ void (* const Ws2812Command[])(void) PROGMEM = {
|
||||||
|
|
||||||
#endif // No USE_WS2812_DMA
|
#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;
|
NeoPixelBus<selectedNeoFeatureType, selectedNeoSpeedType> *strip = nullptr;
|
||||||
|
|
||||||
struct WsColor {
|
struct WsColor {
|
||||||
|
|
Loading…
Reference in New Issue