diff --git a/keywords.txt b/keywords.txt index 0508346..285d3ad 100644 --- a/keywords.txt +++ b/keywords.txt @@ -26,7 +26,10 @@ NeoRbgFeature KEYWORD1 NeoWrgbTm1814Feature KEYWORD1 DotStarBgrFeature KEYWORD1 DotStarLbgrFeature KEYWORD1 +Lpd6803GrbFeature KEYWORD1 +Lpd6803BrgFeature KEYWORD1 Lpd8806GrbFeature KEYWORD1 +Lpd8806BrgFeature KEYWORD1 P9813BgrFeature KEYWORD1 SevenSegmentFeature KEYWORD1 Neo800KbpsMethod KEYWORD1 @@ -375,6 +378,11 @@ NeoWs2801SpiMethod KEYWORD1 NeoWs2801Spi20MhzMethod KEYWORD1 NeoWs2801Spi10MhzMethod KEYWORD1 NeoWs2801Spi2MhzMethod KEYWORD1 +Lpd6803SpiMethod KEYWORD1 +Lpd6803Method KEYWORD1 +Lpd6803Spi20MhzMethod KEYWORD1 +Lpd6803Spi10MhzMethod KEYWORD1 +Lpd6803Spi2MhzMethod KEYWORD1 Lpd8806Method KEYWORD1 Lpd8806SpiMethod KEYWORD1 Lpd8806Spi20MhzMethod KEYWORD1 diff --git a/src/NeoPixelBus.h b/src/NeoPixelBus.h index a80a0fd..277c963 100644 --- a/src/NeoPixelBus.h +++ b/src/NeoPixelBus.h @@ -65,6 +65,7 @@ License along with NeoPixel. If not, see #include "internal/NeoTm1814ColorFeatures.h" #include "internal/DotStarColorFeatures.h" #include "internal/Lpd8806ColorFeatures.h" +#include "internal/Lpd6803ColorFeatures.h" #include "internal/P9813ColorFeatures.h" #include "internal/NeoSegmentFeatures.h" @@ -86,6 +87,7 @@ License along with NeoPixel. If not, see #include "internal/DotStarGenericMethod.h" #include "internal/Lpd8806GenericMethod.h" +#include "internal/Lpd6803GenericMethod.h" #include "internal/Ws2801GenericMethod.h" #include "internal/P9813GenericMethod.h" diff --git a/src/internal/Lpd6803ColorFeatures.h b/src/internal/Lpd6803ColorFeatures.h new file mode 100644 index 0000000..449eace --- /dev/null +++ b/src/internal/Lpd6803ColorFeatures.h @@ -0,0 +1,219 @@ +/*------------------------------------------------------------------------- +Lpd6803ColorFeatures 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 +. +-------------------------------------------------------------------------*/ +#pragma once + +class Lpd68033ElementsNoSettings +{ +public: + typedef NeoNoSettings SettingsObject; + static const size_t SettingsSize = 0; + + static void applySettings(uint8_t*, const SettingsObject&) + { + } + + static uint8_t* pixels(uint8_t* pData) + { + return pData; + } + + static const uint8_t* pixels(const uint8_t* pData) + { + return pData; + } +}; + +class Lpd68033Elements : public Lpd68033ElementsNoSettings +{ +public: + static const size_t PixelSize = 2; // 1 bit + 555 encoded elements + + 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]; + } + } + + 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++; + } + } + + 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++); + } + } + + 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; + } + } + + typedef RgbColor ColorObject; +}; + +class Lpd6803BrgFeature : public Lpd68033Elements +{ +public: + static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) + { + uint16_t* p = reinterpret_cast( getPixelAddress(pPixels, indexPixel) ); + + *p = encodePixel(color); + } + + static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint16_t* p = reinterpret_cast( getPixelAddress(pPixels, indexPixel) ); + + return decodePixel(*p); + } + + static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel); + + uint16_t color555 = pgm_read_word(p); + + return decodePixel(color555); + } + +protected: + static uint16_t encodePixel(ColorObject color) + { + uint16_t color555 = color.B >> 3; + + color555 <<= 5; + color555 |= color.R >> 3; + color555 <<= 5; + color555 |= color.G >> 3; + color555 |= 0x8000; + + return color555; + } + + static ColorObject decodePixel(uint16_t color555) + { + ColorObject color; + + color555 &= 0x7fff; + color.B = (color555 >> 10) & 0x1f; + color.R = (color555 >> 5) & 0x1f; + color.G = (color555) & 0x1f; + + return color; + } +}; + +class Lpd6803GrbFeature : public Lpd68033Elements +{ +public: + static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) + { + uint16_t* p = reinterpret_cast(getPixelAddress(pPixels, indexPixel)); + + *p = encodePixel(color); + } + + static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint16_t* p = reinterpret_cast(getPixelAddress(pPixels, indexPixel)); + + return decodePixel(*p); + } + + static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel); + + uint16_t color555 = pgm_read_word(p); + + return decodePixel(color555); + } + +protected: + static uint16_t encodePixel(ColorObject color) + { + uint16_t color555 = color.G >> 3; + + color555 <<= 5; + color555 |= color.R >> 3; + color555 <<= 5; + color555 |= color.B >> 3; + color555 |= 0x8000; + + return color555; + } + + static ColorObject decodePixel(uint16_t color555) + { + ColorObject color; + + color555 &= 0x7fff; + color.G = (color555 >> 10) & 0x1f; + color.R = (color555 >> 5) & 0x1f; + color.B = (color555) & 0x1f; + return color; + } +}; + + + diff --git a/src/internal/Lpd6803GenericMethod.h b/src/internal/Lpd6803GenericMethod.h new file mode 100644 index 0000000..a98dffe --- /dev/null +++ b/src/internal/Lpd6803GenericMethod.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------- +NeoPixel library helper functions for LPD6803 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 +. +-------------------------------------------------------------------------*/ + +#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 class Lpd6803MethodBase +{ +public: + Lpd6803MethodBase(uint8_t pinClock, uint8_t pinData, uint16_t pixelCount, size_t elementSize, size_t settingsSize) : + _sizeData(pixelCount * elementSize + settingsSize), + _sizeFrame((pixelCount + 7) / 8), // bit for every pixel at least + _wire(pinClock, pinData) + { + _data = static_cast(malloc(_sizeData)); + memset(_data, 0, _sizeData); + } + +#if !defined(__AVR_ATtiny85__) && !defined(ARDUINO_attiny) + Lpd6803MethodBase(uint16_t pixelCount, size_t elementSize, size_t settingsSize) : + Lpd6803MethodBase(SCK, MOSI, pixelCount, elementSize, settingsSize) + { + } +#endif + + + ~Lpd6803MethodBase() + { + free(_data); + } + + 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) + { + const uint8_t startFrame[4] = { 0x00 }; + + _wire.beginTransaction(); + + // start frame + _wire.transmitBytes(startFrame, sizeof(startFrame)); + + // data + _wire.transmitBytes(_data, _sizeData); + + // end frame + // one bit for every pixel with no less than 1 byte + for (size_t frameByte = 0; frameByte < _sizeFrame; frameByte++) + { + _wire.transmitByte(0x00); + } + + _wire.endTransaction(); + } + + uint8_t* getData() const + { + return _data; + }; + + size_t getDataSize() const + { + return _sizeData; + }; + +private: + const size_t _sizeData; // Size of '_data' buffer below + const size_t _sizeFrame; + + T_TWOWIRE _wire; + uint8_t* _data; // Holds LED color values +}; + +typedef Lpd6803MethodBase Lpd6803Method; + +#if !defined(__AVR_ATtiny85__) && !defined(ARDUINO_attiny) +#include "TwoWireSpiImple.h" +typedef Lpd6803MethodBase> Lpd6803Spi20MhzMethod; +typedef Lpd6803MethodBase> Lpd6803Spi10MhzMethod; +typedef Lpd6803MethodBase> Lpd6803Spi2MhzMethod; +typedef Lpd6803Spi10MhzMethod Lpd6803SpiMethod; +#endif + + +