This commit is contained in:
Michael Miller
2024-04-10 22:08:23 -07:00
parent 66218d1fd0
commit 3940d54dfa
14 changed files with 187 additions and 593 deletions

View File

@@ -1,164 +0,0 @@
/*-------------------------------------------------------------------------
NeoPixelBus library wrapper template class that provides overall brightness control
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 "NeoPixelBus.h"
template<typename T_COLOR_FEATURE, typename T_METHOD> class [[deprecated("Use NeoPixelBusLg instead.")]] NeoPixelBrightnessBus :
public NeoPixelBus<T_COLOR_FEATURE, T_METHOD>
{
private:
void ScaleColor(uint16_t scale, typename T_COLOR_FEATURE::ColorObject* color)
{
// This is the similiar as calling Dim on the color object
// there is an assumption that all color elements are byte aligned
// so if any future color object gets introduced that is not it will
// cause a problem
uint8_t* ptr = (uint8_t*)color;
uint8_t* ptrEnd = ptr + sizeof(typename T_COLOR_FEATURE::ColorObject);
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value * scale) >> 8;
}
}
void ConvertColor(typename T_COLOR_FEATURE::ColorObject* color)
{
// This is the same as calling Dim on the color object
uint16_t scale = _brightness + 1;
ScaleColor(scale, color);
}
void RecoverColor(typename T_COLOR_FEATURE::ColorObject* color) const
{
// this is the same as calling Brighton on the color object
// there is an assumption that all color elements are byte aligned
// so if any future color object gets introduced that is not it will
// cause a problem
uint8_t* ptr = (uint8_t*)color;
uint8_t* ptrEnd = ptr + sizeof(typename T_COLOR_FEATURE::ColorObject);
uint16_t scale = _brightness + 1;
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value << 8) / scale;
}
}
public:
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pin) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pin),
_brightness(255)
{
}
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pin, NeoBusChannel channel) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pin, channel),
_brightness(255)
{
}
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pinClock, pinData),
_brightness(255)
{
}
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData, uint8_t pinLatch, uint8_t pinOutputEnable = NOT_A_PIN) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pinClock, pinData, pinLatch, pinOutputEnable),
_brightness(255)
{
}
NeoPixelBrightnessBus(uint16_t countPixels) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels),
_brightness(255)
{
}
void SetBrightness(uint8_t brightness)
{
// Only update if there is a change
if (brightness != _brightness)
{
uint16_t scale = ((static_cast<uint16_t>(brightness) + 1) << 8) / (static_cast<uint16_t>(_brightness) + 1);
// scale existing pixels
//
for (uint16_t indexPixel = 0; indexPixel < NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::PixelCount(); indexPixel++)
{
typename T_COLOR_FEATURE::ColorObject color = NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::GetPixelColor(indexPixel);
ScaleColor(scale, &color);
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::SetPixelColor(indexPixel, color);
}
_brightness = brightness;
this->Dirty();
}
}
uint8_t GetBrightness() const
{
return _brightness;
}
void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
{
ConvertColor(&color);
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::SetPixelColor(indexPixel, color);
}
typename T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
{
typename T_COLOR_FEATURE::ColorObject color = NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::GetPixelColor(indexPixel);
RecoverColor(&color);
return color;
}
void ClearTo(typename T_COLOR_FEATURE::ColorObject color)
{
ConvertColor(&color);
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::ClearTo(color);
};
void ClearTo(typename T_COLOR_FEATURE::ColorObject color, uint16_t first, uint16_t last)
{
ConvertColor(&color);
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::ClearTo(color, first, last);
}
protected:
uint8_t _brightness;
};

View File

@@ -42,103 +42,129 @@ const uint16_t PixelIndex_OutOfBounds = 0xffff;
#include "internal/NeoBusChannel.h"
#include "internal/NeoMethods.h"
template<typename T_COLOR_FEATURE, typename T_METHOD>
// T_COLOR_FEATURE -
// The color feature object that defines bit depth, order, and any settings related
// to them
//
// T_METHOD -
// The led feature objec that defines specific timing and hardware used to send the data
// stream on the pin
//
// T_EXPOSED_COLOR_OBJECT-
// The color object to use for the front buffer, does not need to match the
// T_COLOR_FEATURE::ColorObject but must be auto-converted, so no loss of data
//
template<typename T_COLOR_FEATURE,
typename T_METHOD,
typename T_EXPOSED_COLOR_OBJECT = typename T_COLOR_FEATURE::ColorObject,
typename T_SHADER = NeoShaderNop<T_EXPOSED_COLOR_OBJECT, typename T_COLOR_FEATURE::ColorObject>>
class NeoPixelBus
{
public:
// Constructor: number of LEDs, pin number
// NOTE: Pin Number maybe ignored due to hardware limitations of the method.
NeoPixelBus(uint16_t countPixels, uint8_t pin) :
_countPixels(countPixels),
_state(0),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
_pixels(nullptr),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBus(uint16_t countPixels, uint8_t pin, NeoBusChannel channel) :
_countPixels(countPixels),
_state(0),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, channel)
_pixels(nullptr),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, channel),
_shader()
{
}
NeoPixelBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
_countPixels(countPixels),
_state(0),
_method(pinClock, pinData, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
_pixels(nullptr),
_method(pinClock, pinData, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData, uint8_t pinLatch, uint8_t pinOutputEnable = NOT_A_PIN) :
_countPixels(countPixels),
_state(0),
_method(pinClock, pinData, pinLatch, pinOutputEnable, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
_pixels(nullptr),
_method(pinClock, pinData, pinLatch, pinOutputEnable, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBus(uint16_t countPixels) :
_countPixels(countPixels),
_state(0),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
_pixels(nullptr),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBus(uint16_t countPixels, Stream* pixieStream) :
_countPixels(countPixels),
_state(0),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, pixieStream)
_pixels(nullptr),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, pixieStream),
_shader()
{
}
~NeoPixelBus()
{
delete[] _pixels;
}
/* Is this used anymore
operator NeoBufferContext<T_COLOR_FEATURE>()
{
Dirty(); // we assume you are playing with bits
return NeoBufferContext<T_COLOR_FEATURE>(_pixels(), PixelsSize());
}
*/
void Begin()
{
_method.Initialize();
ClearTo(0);
_initialize();
}
// used by DotStarSpiMethod/DotStarEsp32DmaSpiMethod if pins can be configured
void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
_method.Initialize(sck, miso, mosi, ss);
ClearTo(0);
_initialize();
}
// used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting quad SPI
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
{
_method.Initialize(sck, dat0, dat1, dat2, dat3, ss);
ClearTo(0);
_initialize();
}
// used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting oct SPI
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t dat4, int8_t dat5, int8_t dat6, int8_t dat7, int8_t ss)
{
_method.Initialize(sck, dat0, dat1, dat2, dat3, dat4, dat5, dat6, dat7, ss);
ClearTo(0);
_initialize();
}
void Show(bool maintainBufferConsistency = true)
void SetFeatureSettings(const typename T_COLOR_FEATURE::SettingsObject& settings)
{
if (!IsDirty() && !_method.AlwaysUpdate())
{
return;
}
_featureSettings = settings;
}
_method.Update(maintainBufferConsistency);
void SetMethodSettings(const typename T_METHOD::SettingsObject& settings)
{
_method.applySettings(settings);
}
ResetDirty();
void Show()
{
_method.template Update<T_EXPOSED_COLOR_OBJECT, T_COLOR_FEATURE, T_SHADER>(_pixels,
_countPixels,
_featureSettings,
_shader);
}
inline bool CanShow() const
@@ -146,34 +172,9 @@ public:
return _method.IsReadyToUpdate();
};
bool IsDirty() const
T_EXPOSED_COLOR_OBJECT* Pixels()
{
return (_state & NEO_DIRTY);
};
void Dirty()
{
_state |= NEO_DIRTY;
};
void ResetDirty()
{
_state &= ~NEO_DIRTY;
};
uint8_t* Pixels()
{
return _pixels();
};
size_t PixelsSize() const
{
return _method.getDataSize() - T_COLOR_FEATURE::SettingsSize;
};
size_t PixelSize() const
{
return T_COLOR_FEATURE::PixelSize;
return _pixels;
};
uint16_t PixelCount() const
@@ -185,23 +186,17 @@ public:
{
if (indexPixel < _countPixels)
{
T_COLOR_FEATURE::applyPixelColor(_pixels(), indexPixel, color);
Dirty();
_pixels[indexPixel] = color;
}
};
typename T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
T_EXPOSED_COLOR_OBJECT GetPixelColor(uint16_t indexPixel) const
{
if (indexPixel < _countPixels)
if (indexPixel >= _countPixels)
{
return T_COLOR_FEATURE::retrievePixelColor(_pixels(), indexPixel);
}
else
{
// Pixel # is out of bounds, this will get converted to a
// color object type initialized to 0 (black)
return 0;
}
return _pixels[indexPixel];
};
template <typename T_COLOROBJECT> T_COLOROBJECT GetPixelColor(uint16_t indexPixel) const
@@ -209,33 +204,24 @@ public:
return T_COLOROBJECT(GetPixelColor(indexPixel));
}
void ClearTo(typename T_COLOR_FEATURE::ColorObject color)
void ClearTo(const T_EXPOSED_COLOR_OBJECT& color)
{
uint8_t temp[T_COLOR_FEATURE::PixelSize];
uint8_t* pixels = _pixels();
ClearTo(color, 0, _countPixels - 1);
}
T_COLOR_FEATURE::applyPixelColor(temp, 0, color);
T_COLOR_FEATURE::replicatePixel(pixels, temp, _countPixels);
Dirty();
};
void ClearTo(typename T_COLOR_FEATURE::ColorObject color, uint16_t first, uint16_t last)
void ClearTo(const T_EXPOSED_COLOR_OBJECT& color, uint16_t first, uint16_t last)
{
if (first < _countPixels &&
last < _countPixels &&
first <= last)
{
uint8_t temp[T_COLOR_FEATURE::PixelSize];
uint8_t* pixels = _pixels();
uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
T_EXPOSED_COLOR_OBJECT* pixels = _pixels + last + 1;
T_EXPOSED_COLOR_OBJECT* pixelsFirst = _pixels + first;
T_COLOR_FEATURE::applyPixelColor(temp, 0, color);
T_COLOR_FEATURE::replicatePixel(pFront, temp, last - first + 1);
Dirty();
while (pixelsFirst <= --pixels)
{
*pixels = color;
}
}
}
@@ -263,7 +249,6 @@ public:
if ((_countPixels - 1) >= shiftCount)
{
_shiftLeft(shiftCount, 0, _countPixels - 1);
Dirty();
}
}
@@ -275,7 +260,6 @@ public:
(last - first) >= shiftCount)
{
_shiftLeft(shiftCount, first, last);
Dirty();
}
}
@@ -303,7 +287,6 @@ public:
if ((_countPixels - 1) >= shiftCount)
{
_shiftRight(shiftCount, 0, _countPixels - 1);
Dirty();
}
}
@@ -315,32 +298,19 @@ public:
(last - first) >= shiftCount)
{
_shiftRight(shiftCount, first, last);
Dirty();
}
}
void SwapPixelColor(uint16_t indexPixelOne, uint16_t indexPixelTwo)
{
auto colorOne = GetPixelColor(indexPixelOne);
auto colorTwo = GetPixelColor(indexPixelTwo);
SetPixelColor(indexPixelOne, colorTwo);
SetPixelColor(indexPixelOne, GetPixelColor(indexPixelTwo));
SetPixelColor(indexPixelTwo, colorOne);
};
void SetPixelSettings(const typename T_COLOR_FEATURE::SettingsObject& settings)
{
T_COLOR_FEATURE::applySettings(_method.getData(), _method.getDataSize(), settings);
Dirty();
};
void SetMethodSettings(const typename T_METHOD::SettingsObject& settings)
{
_method.applySettings(settings);
Dirty();
};
uint32_t CalcTotalMilliAmpere(const typename T_COLOR_FEATURE::ColorObject::SettingsObject& settings)
uint32_t CalcTotalMilliAmpere(const typename T_EXPOSED_COLOR_OBJECT::SettingsObject& settings)
{
uint32_t total = 0; // in 1/10th milliamps
@@ -356,86 +326,75 @@ public:
protected:
const uint16_t _countPixels; // Number of RGB LEDs in strip
uint8_t _state; // internal state
T_EXPOSED_COLOR_OBJECT* _pixels;
T_METHOD _method;
T_SHADER _shader;
typename T_COLOR_FEATURE::SettingsObject _featureSettings;
uint8_t* _pixels()
void _initialize()
{
// get pixels data within the data stream
return T_COLOR_FEATURE::pixels(_method.getData(), _method.getDataSize());
}
const uint8_t* _pixels() const
{
// get pixels data within the data stream
return T_COLOR_FEATURE::pixels(_method.getData(), _method.getDataSize());
_pixels = new T_EXPOSED_COLOR_OBJECT[_countPixels];
ClearTo(0);
}
void _rotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
{
// store in temp
uint8_t temp[rotationCount * T_COLOR_FEATURE::PixelSize];
uint8_t* pixels = _pixels();
T_EXPOSED_COLOR_OBJECT temp[rotationCount];
uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
T_COLOR_FEATURE::movePixelsInc(temp, pFront, rotationCount);
for (uint16_t index = 0; index < rotationCount; index++)
{
temp[index] = _pixels[first + index];
}
// shift data
_shiftLeft(rotationCount, first, last);
// move temp back
pFront = T_COLOR_FEATURE::getPixelAddress(pixels, last - (rotationCount - 1));
T_COLOR_FEATURE::movePixelsInc(pFront, temp, rotationCount);
Dirty();
for (uint16_t index = 0; index < rotationCount; index++)
{
_pixels[last - (rotationCount - 1) + index] = temp[index];
}
}
void _shiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
{
uint16_t front = first + shiftCount;
uint16_t count = last - front + 1;
uint8_t* pixels = _pixels();
uint8_t* pFirst = T_COLOR_FEATURE::getPixelAddress(pixels, first);
uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, front);
T_COLOR_FEATURE::movePixelsInc(pFirst, pFront, count);
// intentional no dirty
while (first <= last)
{
_pixels[first++] = _pixels[front++];
}
}
void _rotateRight(uint16_t rotationCount, uint16_t first, uint16_t last)
{
// store in temp
uint8_t temp[rotationCount * T_COLOR_FEATURE::PixelSize];
uint8_t* pixels = _pixels();
T_EXPOSED_COLOR_OBJECT temp[rotationCount];
uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, last - (rotationCount - 1));
T_COLOR_FEATURE::movePixelsDec(temp, pFront, rotationCount);
for (uint16_t index = 0; index < rotationCount; index++)
{
temp[index] = _pixels[last - (rotationCount - 1) + index];
}
// shift data
_shiftRight(rotationCount, first, last);
// move temp back
pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
T_COLOR_FEATURE::movePixelsDec(pFront, temp, rotationCount);
Dirty();
for (uint16_t index = 0; index < rotationCount; index++)
{
_pixels[first + index] = temp[index];
}
}
void _shiftRight(uint16_t shiftCount, uint16_t first, uint16_t last)
{
uint16_t front = first + shiftCount;
uint16_t count = last - front + 1;
uint16_t front = last - shiftCount;
uint8_t* pixels = _pixels();
uint8_t* pFirst = T_COLOR_FEATURE::getPixelAddress(pixels, first);
uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, front);
T_COLOR_FEATURE::movePixelsDec(pFront, pFirst, count);
// intentional no dirty
while (first <= last)
{
_pixels[last--] = _pixels[front--];
}
}
};

View File

@@ -28,6 +28,53 @@ License along with NeoPixel. If not, see
#include "NeoPixelBus.h"
template<typename T_EXPOSED_COLOR_OBJECT,
typename T_FEATURE_COLOR_OBJECT,
typename T_GAMMA>
class LuminanceShader
{
public:
LuminanceShader(typename T_EXPOSED_COLOR_OBJECT::ElementType luminance = T_EXPOSED_COLOR_OBJECT::Max) :
_luminance(luminance)
{
}
T_FEATURE_COLOR_OBJECT Apply(const T_EXPOSED_COLOR_OBJECT& original) const
{
// dim and then return gamma adjusted
T_FEATURE_COLOR_OBJECT color(original.Dim(_luminance));
return NeoGamma<T_GAMMA>::Correct(color);
}
bool setLuminance(typename T_EXPOSED_COLOR_OBJECT::ElementType luminance)
{
bool different = (_luminance != luminance);
if (different)
{
_luminance = luminance;
}
return different;
}
typename T_EXPOSED_COLOR_OBJECT::ElementType getLuminance() const
{
return _luminance;
}
private:
typename T_EXPOSED_COLOR_OBJECT::ElementType _luminance;
};
// T_COLOR_FEATURE -
// The color feature object that defines bit depth, order, and any settings related
// to them
//
// T_METHOD -
// The led feature objec that defines specific timing and hardware used to send the data
// stream on the pin
//
// T_EXPOSED_COLOR_OBJECT-
// The color object to use for the front buffer, does not need to match the
// T_COLOR_FEATURE::ColorObject but must be auto-converted, so no loss of data
@@ -43,257 +90,21 @@ template<typename T_COLOR_FEATURE,
typename T_METHOD,
typename T_EXPOSED_COLOR_OBJECT = typename T_COLOR_FEATURE::ColorObject,
typename T_GAMMA = NeoGammaTableMethod>
class NeoPixelBusLg
class NeoPixelBusLg :
public NeoPixelBus<T_COLOR_FEATURE,
T_METHOD,
T_EXPOSED_COLOR_OBJECT,
LuminanceShader<T_EXPOSED_COLOR_OBJECT, typename T_COLOR_FEATURE::ColorObject, T_GAMMA>>
{
public:
class LuminanceShader
{
public:
LuminanceShader(typename T_EXPOSED_COLOR_OBJECT::ElementType luminance = T_EXPOSED_COLOR_OBJECT::Max) :
_luminance(luminance)
{
}
typename T_COLOR_FEATURE::ColorObject Apply(const T_EXPOSED_COLOR_OBJECT& original) const
{
// dim and then return gamma adjusted
typename T_COLOR_FEATURE::ColorObject color(original.Dim(_luminance));
return NeoGamma<T_GAMMA>::Correct(color);
}
protected:
bool setLuminance(typename T_EXPOSED_COLOR_OBJECT::ElementType luminance)
{
bool different = (_luminance != luminance);
if (different)
{
_luminance = luminance;
}
return different;
}
typename T_EXPOSED_COLOR_OBJECT::ElementType getLuminance() const
{
return _luminance;
}
friend class NeoPixelBusLg;
private:
typename T_EXPOSED_COLOR_OBJECT::ElementType _luminance;
};
public:
NeoPixelBusLg(uint16_t countPixels, uint8_t pin) :
_countPixels(countPixels),
_pixels(nullptr),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBusLg(uint16_t countPixels, uint8_t pin, NeoBusChannel channel) :
_countPixels(countPixels),
_pixels(nullptr),
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, channel),
_shader()
{
}
NeoPixelBusLg(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
_countPixels(countPixels),
_pixels(nullptr),
_method(pinClock, pinData, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBusLg(uint16_t countPixels, uint8_t pinClock, uint8_t pinData, uint8_t pinLatch, uint8_t pinOutputEnable = NOT_A_PIN) :
_countPixels(countPixels),
_pixels(nullptr),
_method(pinClock, pinData, pinLatch, pinOutputEnable, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBusLg(uint16_t countPixels) :
_countPixels(countPixels),
_pixels(nullptr),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize),
_shader()
{
}
NeoPixelBusLg(uint16_t countPixels, Stream* pixieStream) :
_countPixels(countPixels),
_pixels(nullptr),
_method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, pixieStream),
_shader()
{
}
~NeoPixelBusLg()
{
delete [] _pixels;
}
void Begin()
{
_method.Initialize();
_initialize();
}
// used by DotStarSpiMethod/DotStarEsp32DmaSpiMethod if pins can be configured
void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
_method.Initialize(sck, miso, mosi, ss);
_initialize();
}
// used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting quad SPI
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
{
_method.Initialize(sck, dat0, dat1, dat2, dat3, ss);
_initialize();
}
// used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting oct SPI
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t dat4, int8_t dat5, int8_t dat6, int8_t dat7, int8_t ss)
{
_method.Initialize(sck, dat0, dat1, dat2, dat3, dat4, dat5, dat6, dat7, ss);
_initialize();
}
void SetFeatureSettings(const typename T_COLOR_FEATURE::SettingsObject& settings)
{
_featureSettings = settings;
}
void SetMethodSettings(const typename T_METHOD::SettingsObject& settings)
{
_method.applySettings(settings);
}
void Show()
{
_method.template Update<T_EXPOSED_COLOR_OBJECT, T_COLOR_FEATURE, LuminanceShader>(_pixels,
_countPixels,
_featureSettings,
_shader);
}
inline bool CanShow() const
{
return _method.IsReadyToUpdate();
}
uint16_t PixelCount() const
{
return _countPixels;
}
void SetLuminance(typename T_EXPOSED_COLOR_OBJECT::ElementType luminance)
{
_shader.setLuminance(luminance);
this->_shader.setLuminance(luminance);
}
typename T_EXPOSED_COLOR_OBJECT::ElementType GetLuminance() const
{
return _shader.getLuminance();
}
void SetPixelColor(uint16_t indexPixel, const T_EXPOSED_COLOR_OBJECT& color)
{
if (indexPixel < _countPixels)
{
_pixels[indexPixel] = color;
}
}
T_EXPOSED_COLOR_OBJECT GetPixelColor(uint16_t indexPixel) const
{
if (indexPixel >= _countPixels)
{
return 0;
}
return _pixels[indexPixel];
}
void ClearTo(const T_EXPOSED_COLOR_OBJECT& color)
{
ClearTo(color, 0, _countPixels - 1);
}
void ClearTo(const T_EXPOSED_COLOR_OBJECT& color, uint16_t first, uint16_t last)
{
if (first < _countPixels &&
last < _countPixels &&
first <= last)
{
T_EXPOSED_COLOR_OBJECT* pixels = _pixels + last + 1;
T_EXPOSED_COLOR_OBJECT* pixelsFirst = _pixels + first;
while (pixelsFirst <= --pixels)
{
*pixels = color;
}
}
}
// TODO: Move other modification methods over
void RotateLeft(uint16_t rotationCount)
{
if ((_countPixels - 1) >= rotationCount)
{
_rotateLeft(rotationCount, 0, _countPixels - 1);
}
}
protected:
const uint16_t _countPixels;
T_EXPOSED_COLOR_OBJECT* _pixels;
T_METHOD _method;
LuminanceShader _shader;
typename T_COLOR_FEATURE::SettingsObject _featureSettings;
void _initialize()
{
_pixels = new T_EXPOSED_COLOR_OBJECT[_countPixels];
ClearTo(0);
}
void _rotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
{
// store in temp
T_EXPOSED_COLOR_OBJECT temp[rotationCount];
T_EXPOSED_COLOR_OBJECT* pixel = _pixels;
for (uint16_t index = 0; index < rotationCount; index++)
{
temp[index] = _pixels[first + index];
}
// shift data
_shiftLeft(rotationCount, first, last);
// move temp back
for (uint16_t index = 0; index < rotationCount; index++)
{
_pixels[last - (rotationCount - 1) + index] = temp[index];
}
}
void _shiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
{
uint16_t front = first + shiftCount;
while (first <= last)
{
_pixels[first++] = _pixels[front++];
}
return this->_shader.getLuminance();
}
};

View File

@@ -229,9 +229,9 @@ public:
int16_t ySrc,
int16_t wSrc)
{
NeoShaderNop<typename T_COLOR_FEATURE::ColorObject> shaderNop;
NeoShaderNop<typename T_COLOR_FEATURE::ColorObject, typename T_COLOR_FEATURE::ColorObject> shaderNop;
Render<NeoShaderNop<typename T_COLOR_FEATURE::ColorObject>>(destBuffer, shaderNop, indexPixel, xSrc, ySrc, wSrc);
Render<NeoShaderNop<typename T_COLOR_FEATURE::ColorObject, typename T_COLOR_FEATURE::ColorObject>>(destBuffer, shaderNop, indexPixel, xSrc, ySrc, wSrc);
};
template <typename T_SHADER> void Render(NeoBufferContext<T_COLOR_FEATURE> destBuffer,
@@ -285,9 +285,9 @@ public:
int16_t hSrc,
LayoutMapCallback layoutMap)
{
NeoShaderNop<typename T_COLOR_FEATURE::ColorObject> shaderNop;
NeoShaderNop<typename T_COLOR_FEATURE::ColorObject, typename T_COLOR_FEATURE::ColorObject> shaderNop;
Render<NeoShaderNop<typename T_COLOR_FEATURE::ColorObject>>(destBuffer,
Render<NeoShaderNop<typename T_COLOR_FEATURE::ColorObject, typename T_COLOR_FEATURE::ColorObject>>(destBuffer,
shaderNop,
xDest,
yDest,

View File

@@ -25,27 +25,11 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
template<typename T_COLOR_OBJECT> class NeoShaderNop
template<typename T_EXPOSED_COLOR_OBJECT, typename T_FEATURE_COLOR_OBJECT>
class NeoShaderNop
{
public:
NeoShaderNop()
{
}
bool IsDirty() const
{
return true;
};
void Dirty()
{
};
void ResetDirty()
{
};
T_COLOR_OBJECT Apply(uint16_t, T_COLOR_OBJECT color)
static T_FEATURE_COLOR_OBJECT Apply(const T_EXPOSED_COLOR_OBJECT& color)
{
return color;
};

View File

@@ -32,6 +32,7 @@ License along with NeoPixel. If not, see
// ------------------------------------------------------------------------
struct Rgb16Color : RgbColorBase
{
typedef uint8_t ElementType;
typedef NeoRgbCurrentSettings SettingsObject;
// ------------------------------------------------------------------------

View File

@@ -69,7 +69,7 @@ Rgb48Color::Rgb48Color(const HsbColor& color)
B = static_cast<ElementType>(b * Max);
}
ElementType Rgb48Color::CalculateBrightness() const
Rgb48Color::ElementType Rgb48Color::CalculateBrightness() const
{
return static_cast<ElementType>((static_cast<uint32_t>(R) + static_cast<uint32_t>(G) + static_cast<uint32_t>(B)) / 3);
}

View File

@@ -47,7 +47,7 @@ Rgbw64Color::Rgbw64Color(const HsbColor& color)
*this = rgbColor;
}
ElementType Rgbw64Color::CalculateBrightness() const
Rgbw64Color::ElementType Rgbw64Color::CalculateBrightness() const
{
ElementType colorB = static_cast<ElementType>((static_cast<uint32_t>(R) + static_cast<uint32_t>(G) + static_cast<uint32_t>(B)) / 3);
if (W > colorB)

View File

@@ -95,7 +95,7 @@ RgbwColor::RgbwColor(const HsbColor& color)
*this = rgbColor;
}
ElementType RgbwColor::CalculateBrightness() const
RgbwColor::ElementType RgbwColor::CalculateBrightness() const
{
ElementType colorB = static_cast<ElementType>((static_cast<uint16_t>(R) + static_cast<uint16_t>(G) + static_cast<uint16_t>(B)) / 3);
if (W > colorB)

View File

@@ -52,7 +52,7 @@ Rgbww80Color::Rgbww80Color(const Rgbw64Color& color) :
{
};
ElementType Rgbww80Color::CalculateBrightness() const
Rgbww80Color::ElementType Rgbww80Color::CalculateBrightness() const
{
ElementType colorB = static_cast<ElementType>((static_cast<uint32_t>(R) + static_cast<uint32_t>(G) + static_cast<uint32_t>(B)) / 3);
ElementType whiteB = static_cast<ElementType>((static_cast<uint32_t>(WW) + static_cast<uint32_t>(CW)) / 2);

View File

@@ -61,7 +61,7 @@ RgbwwColor::RgbwwColor(const HsbColor& color)
*this = rgbColor;
}
ElementType RgbwwColor::CalculateBrightness() const
RgbwwColor::ElementType RgbwwColor::CalculateBrightness() const
{
ElementType colorB = static_cast<ElementType>((static_cast<uint16_t>(R) + static_cast<uint16_t>(G) + static_cast<uint16_t>(B)) / 3);
ElementType whiteB = static_cast<ElementType>((static_cast<uint16_t>(WW) + static_cast<uint16_t>(CW)) / 2);

View File

@@ -62,7 +62,7 @@ RgbwwwColor::RgbwwwColor(const HsbColor& color)
*this = rgbColor;
}
ElementType RgbwwwColor::CalculateBrightness() const
RgbwwwColor::ElementType RgbwwwColor::CalculateBrightness() const
{
ElementType colorB = static_cast<ElementType>((static_cast<uint16_t>(R) + static_cast<uint16_t>(G) + static_cast<uint16_t>(B)) / 3);
ElementType whiteB = static_cast<ElementType>((static_cast<uint16_t>(W1) + static_cast<uint16_t>(W2) + static_cast<uint16_t>(W3)) / 3);

View File

@@ -108,7 +108,7 @@ SevenSegDigit::SevenSegDigit(char letter, ElementType brightness, ElementType de
}
};
ElementType SevenSegDigit::CalculateBrightness() const
SevenSegDigit::ElementType SevenSegDigit::CalculateBrightness() const
{
uint16_t sum = 0;

View File

@@ -33,16 +33,19 @@ class Neo4WordFeature :
public:
static void applyPixelColor(uint8_t* pixel, size_t pixelSize, ColorObject color)
{
uint8_t* p = getPixelAddress(pPixels, indexPixel);
if (PixelSize <= pixelSize)
{
uint8_t* p = pixel;
// due to endianness the byte order must be copied to output
*p++ = color[V_IC_1] >> 8;
*p++ = color[V_IC_1] & 0xff;
*p++ = color[V_IC_2] >> 8;
*p++ = color[V_IC_2] & 0xff;
*p++ = color[V_IC_3] >> 8;
*p++ = color[V_IC_3] & 0xff;
*p++ = color[V_IC_4] >> 8;
*p = color[V_IC_4] & 0xff;
// due to endianness the byte order must be copied to output
*p++ = color[V_IC_1] >> 8;
*p++ = color[V_IC_1] & 0xff;
*p++ = color[V_IC_2] >> 8;
*p++ = color[V_IC_2] & 0xff;
*p++ = color[V_IC_3] >> 8;
*p++ = color[V_IC_3] & 0xff;
*p++ = color[V_IC_4] >> 8;
*p = color[V_IC_4] & 0xff;
}
}
};