* SpecificMethod
* DotStar and Lpd8806 SPI speeds selectable
This commit is contained in:
Michael Miller
2019-09-22 22:00:00 -07:00
committed by GitHub
parent d83c0c7088
commit 0177b8d519
13 changed files with 686 additions and 359 deletions

View File

@@ -4,7 +4,7 @@
Arduino NeoPixel library Arduino NeoPixel library
A library to control one wire protocol RGB and RGBW leds like APA106, SK6812, WS2811, WS2812 and WS2813 that are commonly refered to as NeoPixels and two wire protocol RGB like APA102 commonly refered to as DotStars. A library to control one wire protocol RGB and RGBW leds like APA106, SK6812, WS2811, WS2812 and WS2813 that are commonly refered to as NeoPixels and two wire protocol RGB like Lpd8806 and APA102 commonly refered to as DotStars.
Supports most Arduino platforms. Supports most Arduino platforms.
This is the most functional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used. This is the most functional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used.

View File

@@ -20,6 +20,7 @@ NeoBrgFeature KEYWORD1
NeoRbgFeature KEYWORD1 NeoRbgFeature KEYWORD1
DotStarBgrFeature KEYWORD1 DotStarBgrFeature KEYWORD1
DotStarLbgrFeature KEYWORD1 DotStarLbgrFeature KEYWORD1
Lpd8806GrbFeature KEYWORD1
Neo800KbpsMethod KEYWORD1 Neo800KbpsMethod KEYWORD1
Neo400KbpsMethod KEYWORD1 Neo400KbpsMethod KEYWORD1
NeoWs2813Method KEYWORD1 NeoWs2813Method KEYWORD1
@@ -123,6 +124,14 @@ NeoEsp32BitBang800KbpsMethod KEYWORD1
NeoEsp32BitBang400KbpsMethod KEYWORD1 NeoEsp32BitBang400KbpsMethod KEYWORD1
DotStarMethod KEYWORD1 DotStarMethod KEYWORD1
DotStarSpiMethod KEYWORD1 DotStarSpiMethod KEYWORD1
DotStarSpi20MhzMethod KEYWORD1
DotStarSpi10MhzMethod KEYWORD1
DotStarSpi2MhzMethod KEYWORD1
Lpd8806Method KEYWORD1
Lpd8806SpiMethod KEYWORD1
Lpd8806Spi20MhzMethod KEYWORD1
Lpd8806Spi10MhzMethod KEYWORD1
Lpd8806Spi2MhzMethod KEYWORD1
NeoPixelAnimator KEYWORD1 NeoPixelAnimator KEYWORD1
AnimUpdateCallback KEYWORD1 AnimUpdateCallback KEYWORD1
AnimationParam KEYWORD1 AnimationParam KEYWORD1

View File

@@ -1,14 +1,14 @@
{ {
"name": "NeoPixelBus", "name": "NeoPixelBus",
"keywords": "NeoPixel, WS2811, WS2812, WS2813, SK6812, DotStar, APA102, APA106, RGB, RGBW", "keywords": "NeoPixel, WS2811, WS2812, WS2813, SK6812, DotStar, APA102, APA106, LPD8806, RGB, RGBW",
"description": "A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102) easy. Supports most Arduino platforms. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.", "description": "A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102, LPD8806) easy. Supports most Arduino platforms. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.",
"homepage": "https://github.com/Makuna/NeoPixelBus/wiki", "homepage": "https://github.com/Makuna/NeoPixelBus/wiki",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/Makuna/NeoPixelBus" "url": "https://github.com/Makuna/NeoPixelBus"
}, },
"version": "2.5.1", "version": "2.5.1",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*" "platforms": "*"
} }

View File

@@ -2,7 +2,7 @@ name=NeoPixelBus by Makuna
version=2.5.1 version=2.5.1
author=Michael C. Miller (makuna@live.com) author=Michael C. Miller (makuna@live.com)
maintainer=Michael C. Miller (makuna@live.com) maintainer=Michael C. Miller (makuna@live.com)
sentence=A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102) easy. sentence=A library that makes controlling NeoPixels (APA106, WS2811, WS2812, WS2813 & SK6812) and DotStars (APA102, LPD8806) easy.
paragraph=Supports most Arduino platforms, including Esp8266 and Esp32. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. Supports Matrix layout of pixels. Includes Gamma corretion object. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI. paragraph=Supports most Arduino platforms, including Esp8266 and Esp32. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. Supports Matrix layout of pixels. Includes Gamma corretion object. For Esp8266 it has three methods of sending NeoPixel data, DMA, UART, and Bit Bang. For Esp32 it has two base methods of sending NeoPixel data, i2s and RMT. For all platforms, there are two methods of sending DotStar data, hardware SPI and software SPI.
category=Display category=Display
url=https://github.com/Makuna/NeoPixelBus/wiki url=https://github.com/Makuna/NeoPixelBus/wiki

View File

@@ -46,6 +46,7 @@ License along with NeoPixel. If not, see
#include "internal/NeoColorFeatures.h" #include "internal/NeoColorFeatures.h"
#include "internal/DotStarColorFeatures.h" #include "internal/DotStarColorFeatures.h"
#include "internal/Lpd8806ColorFeatures.h"
#include "internal/Layouts.h" #include "internal/Layouts.h"
#include "internal/NeoTopology.h" #include "internal/NeoTopology.h"
@@ -63,37 +64,34 @@ License along with NeoPixel. If not, see
#include "internal/NeoEase.h" #include "internal/NeoEase.h"
#include "internal/NeoGamma.h" #include "internal/NeoGamma.h"
#include "internal/DotStarGenericMethod.h"
#include "internal/Lpd8806GenericMethod.h"
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include "internal/NeoEsp8266DmaMethod.h" #include "internal/NeoEsp8266DmaMethod.h"
#include "internal/NeoEsp8266UartMethod.h" #include "internal/NeoEsp8266UartMethod.h"
#include "internal/NeoEspBitBangMethod.h" #include "internal/NeoEspBitBangMethod.h"
#include "internal/DotStarGenericMethod.h"
#elif defined(ARDUINO_ARCH_ESP32) #elif defined(ARDUINO_ARCH_ESP32)
#include "internal/NeoEsp32I2sMethod.h" #include "internal/NeoEsp32I2sMethod.h"
#include "internal/NeoEsp32RmtMethod.h" #include "internal/NeoEsp32RmtMethod.h"
#include "internal/NeoEspBitBangMethod.h" #include "internal/NeoEspBitBangMethod.h"
#include "internal/DotStarGenericMethod.h"
#elif defined(__arm__) // must be before ARDUINO_ARCH_AVR due to Teensy incorrectly having it set #elif defined(__arm__) // must be before ARDUINO_ARCH_AVR due to Teensy incorrectly having it set
#include "internal/NeoArmMethod.h" #include "internal/NeoArmMethod.h"
#include "internal/DotStarGenericMethod.h"
#elif defined(ARDUINO_ARCH_AVR) #elif defined(ARDUINO_ARCH_AVR)
#include "internal/NeoAvrMethod.h" #include "internal/NeoAvrMethod.h"
#include "internal/DotStarAvrMethod.h"
#else #else
#error "Platform Currently Not Supported, please add an Issue at Github/Makuna/NeoPixelBus" #error "Platform Currently Not Supported, please add an Issue at Github/Makuna/NeoPixelBus"
#endif #endif
#if !defined(__AVR_ATtiny85__)
#include "internal/DotStarSpiMethod.h"
#endif
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus

View File

@@ -1,153 +0,0 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for DotStars on AVR (APA102).
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/>.
-------------------------------------------------------------------------*/
#pragma once
// must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
class DotStarAvrMethod
{
public:
DotStarAvrMethod(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
_pinClock(pinClock),
_pinData(pinData),
_sizePixels(pixelCount * elementSize)
{
pinMode(pinClock, OUTPUT);
pinMode(pinData, OUTPUT);
_pixels = (uint8_t*)malloc(_sizePixels);
memset(_pixels, 0, _sizePixels);
_portClock = portOutputRegister(digitalPinToPort(_pinClock));
_pinMaskClock = digitalPinToBitMask(_pinClock);
_portData = portOutputRegister(digitalPinToPort(_pinData));
_pinMaskData = digitalPinToBitMask(_pinData);
}
~DotStarAvrMethod()
{
pinMode(_pinClock, INPUT);
pinMode(_pinData, INPUT);
free(_pixels);
}
bool IsReadyToUpdate() const
{
return true; // dot stars don't have a required delay
}
void Initialize()
{
digitalWrite(_pinClock, LOW);
digitalWrite(_pinData, LOW);
}
void Update(bool)
{
// start frame
for (int startFrameByte = 0; startFrameByte < 4; startFrameByte++)
{
_transmitByte(0x00);
}
// data
uint8_t* data = _pixels;
const uint8_t* endData = _pixels + _sizePixels;
while (data < endData)
{
_transmitByte(*data++);
}
// end frame
// one bit for every two pixels with no less than 1 byte
const uint16_t countEndFrameBytes = ((_sizePixels / 4) + 15) / 16;
for (uint16_t endFrameByte = 0; endFrameByte < countEndFrameBytes; endFrameByte++)
{
_transmitByte(0xff);
}
// set clock and data back to low between updates
digitalWrite(_pinData, LOW);
}
uint8_t* getPixels() const
{
return _pixels;
};
size_t getPixelsSize() const
{
return _sizePixels;
};
private:
const uint8_t _pinClock; // output pin number for clock line
const uint8_t _pinData; // output pin number for data line
const size_t _sizePixels; // Size of '_pixels' buffer below
uint8_t* _pixels; // Holds LED color values
volatile uint8_t* _portData; // Output PORT register
uint8_t _pinMaskData; // Output PORT bitmask
volatile uint8_t* _portClock; // Output PORT register
uint8_t _pinMaskClock; // Output PORT bitmask
void _transmitByte(uint8_t data)
{
for (int bit = 7; bit >= 0; bit--)
{
// set data bit on pin
// digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
if (data & 0x80)
{
*_portData |= _pinMaskData;
}
else
{
*_portData &= ~_pinMaskData;
}
// set clock high as data is ready
// digitalWrite(_pinClock, HIGH);
*_portClock |= _pinMaskClock;
// done between clock toggle to give a little time
data <<= 1;
// set clock low as data pin is changed
// digitalWrite(_pinClock, LOW);
*_portClock &= ~_pinMaskClock;
}
}
};
typedef DotStarAvrMethod DotStarMethod;
#endif

View File

@@ -26,26 +26,33 @@ License along with NeoPixel. If not, see
#pragma once #pragma once
class DotStarGenericMethod // must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
#include "TwoWireBitBangImpleAvr.h"
#else
#include "TwoWireBitBangImple.h"
#endif
template<typename T_TWOWIRE> class DotStarMethodBase
{ {
public: public:
DotStarGenericMethod(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) : DotStarMethodBase(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
_pinClock(pinClock), _sizePixels(pixelCount * elementSize),
_pinData(pinData), _sizeEndFrame((pixelCount + 15) / 16), // 16 = div 2 (bit for every two pixels) div 8 (bits to bytes)
_sizePixels(pixelCount * elementSize) _wire(pinClock, pinData)
{ {
pinMode(pinClock, OUTPUT);
pinMode(pinData, OUTPUT);
_pixels = (uint8_t*)malloc(_sizePixels); _pixels = (uint8_t*)malloc(_sizePixels);
memset(_pixels, 0, _sizePixels); memset(_pixels, 0, _sizePixels);
} }
~DotStarGenericMethod() DotStarMethodBase(uint16_t pixelCount, size_t elementSize) :
{ DotStarMethodBase(SCK, MOSI, pixelCount, elementSize)
pinMode(_pinClock, INPUT); {
pinMode(_pinData, INPUT); }
~DotStarMethodBase()
{
free(_pixels); free(_pixels);
} }
@@ -54,38 +61,38 @@ public:
return true; // dot stars don't have a required delay return true; // dot stars don't have a required delay
} }
#if defined(ARDUINO_ARCH_ESP32)
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
_wire.begin(sck, miso, mosi, ss);
}
#endif
void Initialize() void Initialize()
{ {
digitalWrite(_pinClock, LOW); _wire.begin();
digitalWrite(_pinData, LOW);
} }
void Update(bool) void Update(bool)
{ {
const uint8_t startFrame[4] = { 0x00 };
_wire.beginTransaction();
// start frame // start frame
for (int startFrameByte = 0; startFrameByte < 4; startFrameByte++) _wire.transmitBytes(startFrame, sizeof(startFrame));
{
_transmitByte(0x00);
}
// data // data
uint8_t* data = _pixels; _wire.transmitBytes(_pixels, _sizePixels);
const uint8_t* endData = _pixels + _sizePixels;
while (data < endData)
{
_transmitByte(*data++);
}
// end frame // end frame
// one bit for every two pixels with no less than 1 byte // one bit for every two pixels with no less than 1 byte
const uint16_t countEndFrameBytes = ((_sizePixels / 4) + 15) / 16; for (size_t endFrameByte = 0; endFrameByte < _sizeEndFrame; endFrameByte++)
for (uint16_t endFrameByte = 0; endFrameByte < countEndFrameBytes; endFrameByte++) {
{ _wire.transmitByte(0xff);
_transmitByte(0xff); }
}
// set clock and data back to low between updates _wire.endTransaction();
digitalWrite(_pinData, LOW);
} }
uint8_t* getPixels() const uint8_t* getPixels() const
@@ -99,30 +106,22 @@ public:
}; };
private: private:
const uint8_t _pinClock; // output pin number for clock line const size_t _sizePixels; // Size of '_pixels' buffer below
const uint8_t _pinData; // output pin number for data line const size_t _sizeEndFrame;
const size_t _sizePixels; // Size of '_pixels' buffer below
T_TWOWIRE _wire;
uint8_t* _pixels; // Holds LED color values uint8_t* _pixels; // Holds LED color values
void _transmitByte(uint8_t data)
{
for (int bit = 7; bit >= 0; bit--)
{
// set data bit on pin
digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
// set clock high as data is ready
digitalWrite(_pinClock, HIGH);
data <<= 1;
// set clock low as data pin is changed
digitalWrite(_pinClock, LOW);
}
}
}; };
typedef DotStarGenericMethod DotStarMethod; typedef DotStarMethodBase<TwoWireBitBangImple> DotStarMethod;
#if !defined(__AVR_ATtiny85__)
#include "TwoWireSpiImple.h"
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> DotStarSpi20MhzMethod;
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> DotStarSpi10MhzMethod;
typedef DotStarMethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> DotStarSpi2MhzMethod;
typedef DotStarSpi10MhzMethod DotStarSpiMethod;
#endif

View File

@@ -1,133 +0,0 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for DotStars using SPI hardware (APA102).
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/>.
-------------------------------------------------------------------------*/
#pragma once
#include <SPI.h>
class DotStarSpiMethod
{
public:
DotStarSpiMethod(uint16_t pixelCount, size_t elementSize) :
_sizeData(pixelCount * elementSize),
_sizeSendBuffer(calcBufferSize(pixelCount * elementSize))
{
_sendBuffer = (uint8_t*)malloc(_sizeSendBuffer);
memset(_sendBuffer, 0, _sizeSendBuffer);
setEndFrameBytes();
}
~DotStarSpiMethod()
{
SPI.end();
free(_sendBuffer);
}
bool IsReadyToUpdate() const
{
return true; // dot stars don't have a required delay
}
#if defined(ARDUINO_ARCH_ESP32)
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
SPI.begin(sck, miso, mosi, ss);
}
#endif
void Initialize()
{
SPI.begin();
}
void Update(bool)
{
SPI.beginTransaction(SPISettings(20000000L, MSBFIRST, SPI_MODE0));
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
// ESPs have a method to write without inplace overwriting the send buffer
// since we don't care what gets received, use it for performance
SPI.writeBytes(_sendBuffer, _sizeSendBuffer);
#else
// default ARDUINO transfer inplace overwrites the send buffer
// which is bad, so we have to send one byte at a time
uint8_t* out = _sendBuffer;
uint8_t* end = out + _sizeSendBuffer;
while (out < end)
{
SPI.transfer(*out++);
}
#endif
SPI.endTransaction();
}
uint8_t* getPixels() const
{
return _sendBuffer + _countStartFrame;
};
size_t getPixelsSize() const
{
return _sizeData;
};
private:
const size_t _countStartFrame = 4;
const size_t _sizeData; // size of actuall pixel data within _sendBuffer
const size_t _sizeSendBuffer; // Size of '_sendBuffer' buffer below
uint8_t* _sendBuffer; // Holds SPI send Buffer, including LED color values
size_t calcBufferSize(size_t sizePixels) const
{
const size_t countEndFrameBytes = calcEndFrameSize(sizePixels);
// start frame + data + end frame
const size_t bufferSize = _countStartFrame + sizePixels + countEndFrameBytes;
return bufferSize;
}
size_t calcEndFrameSize(size_t sizePixels) const
{
// end frame
// one bit for every two pixels with no less than 1 byte
return ((sizePixels / 4) + 15) / 16;
}
void setEndFrameBytes()
{
uint8_t* pEndFrame = _sendBuffer + _countStartFrame + _sizeData;
uint8_t* pEndFrameStop = pEndFrame + calcEndFrameSize(_sizeData);
while (pEndFrame != pEndFrameStop)
{
*pEndFrame++ = 0xff;
}
}
};

View File

@@ -0,0 +1,167 @@
/*-------------------------------------------------------------------------
Lpd8806ColorFeatures provides feature classes to describe color order and
color depth for NeoPixelBus template class when used with DotStar like chips
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/>.
-------------------------------------------------------------------------*/
#pragma once
class Lpd88063Elements
{
public:
static const size_t PixelSize = 3;
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static const uint8_t* getPixelAddress(const uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
while (pPixelDest < pEnd)
{
*pPixelDest++ = pPixelSrc[0];
*pPixelDest++ = pPixelSrc[1];
*pPixelDest++ = pPixelSrc[2];
}
}
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
while (pPixelDest < pEnd)
{
*pPixelDest++ = *pPixelSrc++;
*pPixelDest++ = *pPixelSrc++;
*pPixelDest++ = *pPixelSrc++;
}
}
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
const uint8_t* pSrc = (const uint8_t*)pPixelSrc;
while (pPixelDest < pEnd)
{
*pPixelDest++ = pgm_read_byte(pSrc++);
*pPixelDest++ = pgm_read_byte(pSrc++);
*pPixelDest++ = pgm_read_byte(pSrc++);
}
}
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pDestBack = pPixelDest + (count * PixelSize);
const uint8_t* pSrcBack = pPixelSrc + (count * PixelSize);
while (pDestBack > pPixelDest)
{
*--pDestBack = *--pSrcBack;
*--pDestBack = *--pSrcBack;
*--pDestBack = *--pSrcBack;
}
}
typedef RgbColor ColorObject;
};
class Lpd8806BrgFeature : public Lpd88063Elements
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
{
uint8_t* p = getPixelAddress(pPixels, indexPixel);
*p++ = (color.B >> 1) | 0x80;
*p++ = (color.R >> 1) | 0x80;
*p = (color.G >> 1) | 0x80;
}
static ColorObject retrievePixelColor(uint8_t* pPixels, uint16_t indexPixel)
{
ColorObject color;
uint8_t* p = getPixelAddress(pPixels, indexPixel);
color.B = (*p++) << 1;
color.R = (*p++) << 1;
color.G = (*p) << 1;
return color;
}
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
color.B = (pgm_read_byte(p++)) << 1;
color.R = (pgm_read_byte(p++)) << 1;
color.G = (pgm_read_byte(p)) << 1;
return color;
}
};
class Lpd8806GrbFeature : public Lpd88063Elements
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
{
uint8_t* p = getPixelAddress(pPixels, indexPixel);
*p++ = (color.G >> 1) | 0x80;
*p++ = (color.R >> 1) | 0x80;
*p = (color.B >> 1) | 0x80;
}
static ColorObject retrievePixelColor(uint8_t* pPixels, uint16_t indexPixel)
{
ColorObject color;
uint8_t* p = getPixelAddress(pPixels, indexPixel);
color.G = (*p++) << 1;
color.R = (*p++) << 1;
color.B = (*p) << 1;
return color;
}
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
color.G = (pgm_read_byte(p++)) << 1;
color.R = (pgm_read_byte(p++)) << 1;
color.B = (pgm_read_byte(p)) << 1;
return color;
}
};

View File

@@ -0,0 +1,127 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for LPD8806 using general Pins
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/>.
-------------------------------------------------------------------------*/
#pragma once
// must also check for arm due to Teensy incorrectly having ARDUINO_ARCH_AVR set
#if defined(ARDUINO_ARCH_AVR) && !defined(__arm__)
#include "TwoWireBitBangImpleAvr.h"
#else
#include "TwoWireBitBangImple.h"
#endif
template<typename T_TWOWIRE> class Lpd8806MethodBase
{
public:
Lpd8806MethodBase(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize) :
_sizePixels(pixelCount * elementSize),
_sizeFrame((pixelCount + 31) / 32),
_wire(pinClock, pinData)
{
_pixels = (uint8_t*)malloc(_sizePixels);
memset(_pixels, 0, _sizePixels);
}
Lpd8806MethodBase(uint16_t pixelCount, size_t elementSize) :
Lpd8806MethodBase(SCK, MOSI, pixelCount, elementSize)
{
}
~Lpd8806MethodBase()
{
free(_pixels);
}
bool IsReadyToUpdate() const
{
return true; // dot stars don't have a required delay
}
#if defined(ARDUINO_ARCH_ESP32)
void Initialize(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
_wire.begin(sck, miso, mosi, ss);
}
#endif
void Initialize()
{
_wire.begin();
}
void Update(bool)
{
_wire.beginTransaction();
// start frame
for (size_t frameByte = 0; frameByte < _sizeFrame; frameByte++)
{
_wire.transmitByte(0x00);
}
// data
_wire.transmitBytes(_pixels, _sizePixels);
// end frame
for (size_t frameByte = 0; frameByte < _sizeFrame; frameByte++)
{
_wire.transmitByte(0xff);
}
_wire.endTransaction();
}
uint8_t* getPixels() const
{
return _pixels;
};
size_t getPixelsSize() const
{
return _sizePixels;
};
private:
const size_t _sizePixels; // Size of '_pixels' buffer below
const size_t _sizeFrame;
T_TWOWIRE _wire;
uint8_t* _pixels; // Holds LED color values
};
typedef Lpd8806MethodBase<TwoWireBitBangImple> Lpd8806Method;
#if !defined(__AVR_ATtiny85__)
#include "TwoWireSpiImple.h"
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed20Mhz>> Lpd8806Spi20MhzMethod;
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed10Mhz>> Lpd8806Spi10MhzMethod;
typedef Lpd8806MethodBase<TwoWireSpiImple<SpiSpeed2Mhz>> Lpd8806Spi2MhzMethod;
typedef Lpd8806Spi10MhzMethod Lpd8806SpiMethod;
#endif

View File

@@ -0,0 +1,92 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
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/>.
-------------------------------------------------------------------------*/
#pragma once
class TwoWireBitBangImple
{
public:
TwoWireBitBangImple(uint8_t pinClock, uint8_t pinData) :
_pinClock(pinClock),
_pinData(pinData)
{
pinMode(pinClock, OUTPUT);
pinMode(pinData, OUTPUT);
}
~TwoWireBitBangImple()
{
pinMode(_pinClock, INPUT);
pinMode(_pinData, INPUT);
}
void begin()
{
digitalWrite(_pinClock, LOW);
digitalWrite(_pinData, LOW);
}
void beginTransaction()
{
}
void endTransaction()
{
digitalWrite(_pinData, LOW);
}
void transmitByte(uint8_t data)
{
for (int bit = 7; bit >= 0; bit--)
{
// set data bit on pin
digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
// set clock high as data is ready
digitalWrite(_pinClock, HIGH);
data <<= 1;
// set clock low as data pin is changed
digitalWrite(_pinClock, LOW);
}
}
void transmitBytes(const uint8_t* data, size_t dataSize)
{
const uint8_t* endData = data + dataSize;
while (data < endData)
{
transmitByte(*data++);
}
}
private:
const uint8_t _pinClock; // output pin number for clock line
const uint8_t _pinData; // output pin number for data line
};

View File

@@ -0,0 +1,112 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
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/>.
-------------------------------------------------------------------------*/
#pragma once
class TwoWireBitBangImple
{
public:
TwoWireBitBangImple(uint8_t pinClock, uint8_t pinData) :
_pinClock(pinClock),
_pinData(pinData)
{
pinMode(pinClock, OUTPUT);
pinMode(pinData, OUTPUT);
_portClock = portOutputRegister(digitalPinToPort(_pinClock));
_pinMaskClock = digitalPinToBitMask(_pinClock);
_portData = portOutputRegister(digitalPinToPort(_pinData));
_pinMaskData = digitalPinToBitMask(_pinData);
}
~TwoWireBitBangImple()
{
pinMode(_pinClock, INPUT);
pinMode(_pinData, INPUT);
}
void begin()
{
digitalWrite(_pinClock, LOW);
digitalWrite(_pinData, LOW);
}
void beginTransaction()
{
}
void endTransaction()
{
digitalWrite(_pinData, LOW);
}
void transmitByte(uint8_t data)
{
for (int bit = 7; bit >= 0; bit--)
{
// set data bit on pin
// digitalWrite(_pinData, (data & 0x80) == 0x80 ? HIGH : LOW);
if (data & 0x80)
{
*_portData |= _pinMaskData;
}
else
{
*_portData &= ~_pinMaskData;
}
// set clock high as data is ready
// digitalWrite(_pinClock, HIGH);
*_portClock |= _pinMaskClock;
data <<= 1;
// set clock low as data pin is changed
// digitalWrite(_pinClock, LOW);
*_portClock &= ~_pinMaskClock;
}
}
void transmitBytes(const uint8_t* data, size_t dataSize)
{
const uint8_t* endData = data + dataSize;
while (data < endData)
{
transmitByte(*data++);
}
}
private:
const uint8_t _pinClock; // output pin number for clock line
const uint8_t _pinData; // output pin number for data line
volatile uint8_t* _portData; // Output PORT register
uint8_t _pinMaskData; // Output PORT bitmask
volatile uint8_t* _portClock; // Output PORT register
uint8_t _pinMaskClock; // Output PORT bitmask
};

View File

@@ -0,0 +1,109 @@
/*-------------------------------------------------------------------------
NeoPixel library helper functions for DotStars using general Pins (APA102/LPD8806).
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/>.
-------------------------------------------------------------------------*/
#pragma once
#include <SPI.h>
class SpiSpeed20Mhz
{
public:
static const uint32_t Clock = 20000000L;
};
class SpiSpeed10Mhz
{
public:
static const uint32_t Clock = 10000000L;
};
class SpiSpeed2Mhz
{
public:
static const uint32_t Clock = 2000000L;
};
template<typename T_SPISPEED> class TwoWireSpiImple
{
public:
TwoWireSpiImple(uint8_t, uint8_t) // clock and data pins ignored for hardware SPI
{
}
~TwoWireSpiImple()
{
SPI.end();
}
#if defined(ARDUINO_ARCH_ESP32)
// for cases where hardware SPI can have pins changed
void begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
SPI.begin(sck, miso, mosi, ss);
}
#endif
void begin()
{
SPI.begin();
}
void beginTransaction()
{
SPI.beginTransaction(SPISettings(T_SPISPEED::Clock, MSBFIRST, SPI_MODE0));
}
void endTransaction()
{
SPI.endTransaction();
}
void transmitByte(uint8_t data)
{
SPI.transfer(data);
}
void transmitBytes(const uint8_t* data, size_t dataSize)
{
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
// ESPs have a method to write without inplace overwriting the send buffer
// since we don't care what gets received, use it for performance
// FIX: but for what ever reason on Esp32, its not const
SPI.writeBytes(const_cast<uint8_t*>(data), dataSize);
#else
// default ARDUINO transfer inplace overwrites the send buffer
// which is bad in this case, so we have to send one byte at a time
const uint8_t* endData = data + dataSize;
while (data < endData)
{
SPI.transfer(*data++);
}
#endif
}
private:
};