forked from Makuna/NeoPixelBus
BitBang enhancements (#286)
This commit is contained in:
@@ -185,10 +185,10 @@ typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeedSk6812> NeoEsp8266BitBangSk681
|
|||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps> NeoEsp8266BitBang800KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed800Kbps> NeoEsp8266BitBang800KbpsMethod;
|
||||||
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps> NeoEsp8266BitBang400KbpsMethod;
|
typedef NeoEspBitBangMethodBase<NeoEspBitBangSpeed400Kbps> NeoEsp8266BitBang400KbpsMethod;
|
||||||
|
|
||||||
typedef NeoEsp8266BitBangWs2812xMethod NeoEsp32BitBangWs2813Method;
|
typedef NeoEsp8266BitBangWs2812xMethod NeoEsp8266BitBangWs2813Method;
|
||||||
typedef NeoEsp8266BitBang800KbpsMethod NeoEsp32BitBangWs2812Method;
|
typedef NeoEsp8266BitBang800KbpsMethod NeoEsp8266BitBangWs2812Method;
|
||||||
typedef NeoEsp8266BitBangSk6812Method NeoEsp32BitBangLc8812Method;
|
typedef NeoEsp8266BitBangSk6812Method NeoEsp8266BitBangLc8812Method;
|
||||||
typedef NeoEsp8266BitBang400KbpsMethod NeoEsp32BitBangApa106Method;
|
typedef NeoEsp8266BitBang400KbpsMethod NeoEsp8266BitBangApa106Method;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP bitbang doesn't have defaults and should avoided except for testing
|
// ESP bitbang doesn't have defaults and should avoided except for testing
|
||||||
|
@@ -36,7 +36,9 @@ License along with NeoPixel. If not, see
|
|||||||
#define ICACHE_RAM_ATTR IRAM_ATTR
|
#define ICACHE_RAM_ATTR IRAM_ATTR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline uint32_t _getCycleCount()
|
static uint32_t _getCycleCount(void) __attribute__((always_inline));
|
||||||
|
|
||||||
|
static inline uint32_t _getCycleCount(void)
|
||||||
{
|
{
|
||||||
uint32_t ccount;
|
uint32_t ccount;
|
||||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||||
@@ -53,29 +55,23 @@ inline uint32_t _getCycleCount()
|
|||||||
void ICACHE_RAM_ATTR bitbang_send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
void ICACHE_RAM_ATTR bitbang_send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
||||||
{
|
{
|
||||||
const uint32_t pinRegister = _BV(pin);
|
const uint32_t pinRegister = _BV(pin);
|
||||||
uint8_t mask;
|
uint8_t mask = 0x80;
|
||||||
uint8_t subpix;
|
uint8_t subpix = *pixels++;
|
||||||
uint32_t cyclesStart;
|
uint32_t cyclesStart = 0; // trigger emediately
|
||||||
|
uint32_t cyclesNext = 0;
|
||||||
|
|
||||||
// trigger emediately
|
for (;;)
|
||||||
cyclesStart = _getCycleCount() - CYCLES_800;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
subpix = *pixels++;
|
|
||||||
for (mask = 0x80; mask != 0; mask >>= 1)
|
|
||||||
{
|
{
|
||||||
// do the checks here while we are waiting on time to pass
|
// do the checks here while we are waiting on time to pass
|
||||||
uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_800_T1H : CYCLES_800_T0H;
|
uint32_t cyclesBit = CYCLES_800_T0H;
|
||||||
uint32_t cyclesNext = cyclesStart;
|
if (subpix & mask)
|
||||||
|
{
|
||||||
|
cyclesBit = CYCLES_800_T1H;
|
||||||
|
}
|
||||||
|
|
||||||
// after we have done as much work as needed for this next bit
|
// after we have done as much work as needed for this next bit
|
||||||
// now wait for the HIGH
|
// now wait for the HIGH
|
||||||
do
|
while (((cyclesStart = _getCycleCount()) - cyclesNext) < CYCLES_800);
|
||||||
{
|
|
||||||
// cache and use this count so we don't incur another
|
|
||||||
// instruction before we turn the bit high
|
|
||||||
cyclesStart = _getCycleCount();
|
|
||||||
} while ((cyclesStart - cyclesNext) < CYCLES_800);
|
|
||||||
|
|
||||||
// set high
|
// set high
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
@@ -85,10 +81,7 @@ void ICACHE_RAM_ATTR bitbang_send_pixels_800(uint8_t* pixels, uint8_t* end, uint
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// wait for the LOW
|
// wait for the LOW
|
||||||
do
|
while ((_getCycleCount() - cyclesStart) < cyclesBit);
|
||||||
{
|
|
||||||
cyclesNext = _getCycleCount();
|
|
||||||
} while ((cyclesNext - cyclesStart) < cyclesBit);
|
|
||||||
|
|
||||||
// set low
|
// set low
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
@@ -96,36 +89,48 @@ void ICACHE_RAM_ATTR bitbang_send_pixels_800(uint8_t* pixels, uint8_t* end, uint
|
|||||||
#else
|
#else
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
||||||
#endif
|
#endif
|
||||||
|
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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (pixels < end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICACHE_RAM_ATTR bitbang_send_pixels_400(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
void ICACHE_RAM_ATTR bitbang_send_pixels_400(uint8_t* pixels, uint8_t* end, uint8_t pin)
|
||||||
{
|
{
|
||||||
const uint32_t pinRegister = _BV(pin);
|
const uint32_t pinRegister = _BV(pin);
|
||||||
uint8_t mask;
|
uint8_t mask = 0x80;
|
||||||
uint8_t subpix;
|
uint8_t subpix = *pixels++;
|
||||||
uint32_t cyclesStart;
|
uint32_t cyclesStart = 0; // trigger emediately
|
||||||
|
uint32_t cyclesNext = 0;
|
||||||
|
|
||||||
// trigger emediately
|
for (;;)
|
||||||
cyclesStart = _getCycleCount() - CYCLES_400;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
subpix = *pixels++;
|
// do the checks here while we are waiting on time to pass
|
||||||
for (mask = 0x80; mask; mask >>= 1)
|
uint32_t cyclesBit = CYCLES_400_T0H;
|
||||||
|
if (subpix & mask)
|
||||||
{
|
{
|
||||||
uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_400_T1H : CYCLES_400_T0H;
|
cyclesBit = CYCLES_400_T1H;
|
||||||
uint32_t cyclesNext = cyclesStart;
|
}
|
||||||
|
|
||||||
// after we have done as much work as needed for this next bit
|
// after we have done as much work as needed for this next bit
|
||||||
// now wait for the HIGH
|
// now wait for the HIGH
|
||||||
do
|
while (((cyclesStart = _getCycleCount()) - cyclesNext) < CYCLES_400);
|
||||||
{
|
|
||||||
// cache and use this count so we don't incur another
|
|
||||||
// instruction before we turn the bit high
|
|
||||||
cyclesStart = _getCycleCount();
|
|
||||||
} while ((cyclesStart - cyclesNext) < CYCLES_400);
|
|
||||||
|
|
||||||
|
// set high
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
GPIO.out_w1ts = pinRegister;
|
GPIO.out_w1ts = pinRegister;
|
||||||
#else
|
#else
|
||||||
@@ -133,10 +138,7 @@ void ICACHE_RAM_ATTR bitbang_send_pixels_400(uint8_t* pixels, uint8_t* end, uint
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// wait for the LOW
|
// wait for the LOW
|
||||||
do
|
while ((_getCycleCount() - cyclesStart) < cyclesBit);
|
||||||
{
|
|
||||||
cyclesNext = _getCycleCount();
|
|
||||||
} while ((cyclesNext - cyclesStart) < cyclesBit);
|
|
||||||
|
|
||||||
// set low
|
// set low
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
@@ -144,8 +146,24 @@ void ICACHE_RAM_ATTR bitbang_send_pixels_400(uint8_t* pixels, uint8_t* end, uint
|
|||||||
#else
|
#else
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
||||||
#endif
|
#endif
|
||||||
|
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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (pixels < end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user