diff --git a/keywords.txt b/keywords.txt index 77ac15c..473d7b0 100644 --- a/keywords.txt +++ b/keywords.txt @@ -19,7 +19,10 @@ HtmlColor KEYWORD1 NeoNoSettings KEYWORD1 NeoTm1814Settings KEYWORD1 NeoTm1914Settings KEYWORD1 -NeoSm168xxSettings KEYWORD1 +NeoSm16803pbSettings KEYWORD1 +NeoSm16823eSettings KEYWORD1 +NeoSm16804ebSettings KEYWORD1 +NeoSm16824eSettings KEYWORD1 NeoSpiSettings KEYWORD1 NeoGrbFeature KEYWORD1 NeoGrbwFeature KEYWORD1 @@ -35,7 +38,10 @@ NeoRgbwUcs8904Feature KEYWORD1 NeoWrgbTm1814Feature KEYWORD1 NeoRgbTm1914Feature KEYWORD1 NeoGrbTm1914Feature KEYWORD1 -NeoRgbwSm168xxFeature KEYWORD1 +NeoRgbSm16803pbColorFeature KEYWORD1 +NeoRgbSm16823eColorFeature KEYWORD1 +NeoRgbwSm16804ebColorFeature KEYWORD1 +NeoRgbwSm16824eColorFeature KEYWORD1 DotStarBgrFeature KEYWORD1 DotStarLbgrFeature KEYWORD1 Lpd6803GrbFeature KEYWORD1 diff --git a/src/internal/NeoSettings.h b/src/internal/NeoSettings.h index 1af9f82..e85d115 100644 --- a/src/internal/NeoSettings.h +++ b/src/internal/NeoSettings.h @@ -51,12 +51,12 @@ public: RedTenthMilliAmpere(red), GreenTenthMilliAmpere(green), BlueTenthMilliAmpere(blue), - WhiteCurrent(white) + WhiteTenthMilliAmpere(white) { } uint16_t RedTenthMilliAmpere; // in 1/10th ma uint16_t GreenTenthMilliAmpere; // in 1/10th ma uint16_t BlueTenthMilliAmpere; // in 1/10th ma - uint16_t WhiteCurrent; // in 1/10th ma + uint16_t WhiteTenthMilliAmpere; // in 1/10th ma }; \ No newline at end of file diff --git a/src/internal/NeoSm168xxColorFeatures.h b/src/internal/NeoSm168xxColorFeatures.h index 75e2fa9..97c0984 100644 --- a/src/internal/NeoSm168xxColorFeatures.h +++ b/src/internal/NeoSm168xxColorFeatures.h @@ -25,52 +25,159 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ #pragma once +/* +3 channel RGB +SM16803P 1.8~60mA << need spec sheet to get accurate implementation +SM16813PB 1.8~19mA +SM16823E 60~350mA +4 channel RGBW +SM16804PB 1.5~60mA << need spec sheet to get accurate implementation +SM16804EB 1.8~19mA +SM16824E 60~350mA +*/ -class NeoSm168xxSettings : public NeoRgbwCurrentSettings +class NeoSm168x3SettingsBase : public NeoRgbCurrentSettings { public: - NeoSm168xxSettings(uint16_t red, uint16_t green, uint16_t blue, uint16_t white) : - NeoRgbwCurrentSettings(red, green, blue, white) - { - } + NeoSm168x3SettingsBase(uint16_t encoded = 0) : + NeoRgbCurrentSettings(0,0,0), + Encoded(encoded) {} - const static uint16_t MinCurrent = 60; - const static uint16_t MaxCurrent = 350; - - static uint16_t LimitCurrent(uint16_t value) - { - if (value < MinCurrent) - { - value = MinCurrent; - } - else if (value > MaxCurrent) - { - value = MaxCurrent; - } - return value; - } + uint16_t Encoded; }; -class Neo4ByteElementsSm168xxSettings : public Neo4ByteElements +class NeoSm16803pbSettings : public NeoSm168x3SettingsBase { -private: - const static uint16_t EncodeDivisor = 19; - public: - typedef NeoSm168xxSettings SettingsObject; + NeoSm16803pbSettings(uint8_t redGain, uint8_t greenGain, uint8_t blueGain) + { + redGain &= 0x0f; + greenGain &= 0x0f; + blueGain &= 0x0f; + + RedTenthMilliAmpere = CurrentLookup[redGain]; + GreenTenthMilliAmpere = CurrentLookup[greenGain]; + BlueTenthMilliAmpere = CurrentLookup[blueGain]; + + // 0RGB 4 bits each + Encoded = redGain << 8 | greenGain << 4 | blueGain; + } + +protected: + static constexpr uint8_t CurrentLookup[16] = { + 18, 30, 41, 53, 64, 76, 87, 99, + 110, 133, 145, 156, 168, 179, 19}; +}; + +class NeoSm16823eSettings : public NeoSm168x3SettingsBase +{ +public: + NeoSm16823eSettings(uint8_t redGain, uint8_t greenGain, uint8_t blueGain, uint16_t resisterOhms) : + extROhms(resisterOhms) + { + redGain &= 0x0f; + greenGain &= 0x0f; + blueGain &= 0x0f; + + RedTenthMilliAmpere = calcCurrent(extROhms, redGain); + GreenTenthMilliAmpere = calcCurrent(extROhms, greenGain); + BlueTenthMilliAmpere = calcCurrent(extROhms, blueGain); + + // RGB0 4 bits each + Encoded = redGain << 12 | greenGain << 8 | blueGain << 4; + } + +protected: + const uint16_t extROhms; + + static uint16_t calcCurrent(const uint16_t ohms, const uint8_t gain) + { + uint16_t mA = (967 / ohms * (240 + (gain * 32))); // from spec sheet, gain 0-15 instead + return mA * 10; // return tenths of mA + } + +}; + +// RGBW versions + +class NeoSm168x4SettingsBase : public NeoRgbwCurrentSettings +{ +public: + NeoSm168x4SettingsBase(uint16_t encoded = 0) : + NeoRgbwCurrentSettings(0,0,0,0), + Encoded(encoded) {} + + uint16_t Encoded; +}; + +class NeoSm16804ebSettings : public NeoSm168x4SettingsBase +{ +public: + NeoSm16804ebSettings(uint8_t redGain, uint8_t greenGain, uint8_t blueGain, uint8_t whiteGain) + { + redGain &= 0x0f; + greenGain &= 0x0f; + blueGain &= 0x0f; + whiteGain &= 0x0f; + + RedTenthMilliAmpere = CurrentLookup[redGain]; + GreenTenthMilliAmpere = CurrentLookup[greenGain]; + BlueTenthMilliAmpere = CurrentLookup[blueGain]; + WhiteTenthMilliAmpere = CurrentLookup[whiteGain]; + + // RGBW 4 bits each + Encoded = redGain << 12 | greenGain << 8 | blueGain << 4 | whiteGain; + } + +protected: + static constexpr uint8_t CurrentLookup[16] = { + 18, 30, 41, 53, 64, 76, 87, 99, + 110, 133, 145, 156, 168, 179, 19 }; +}; + +class NeoSm16824eSettings : public NeoSm168x4SettingsBase +{ +public: + NeoSm16824eSettings(uint8_t redGain, uint8_t greenGain, uint8_t blueGain, uint8_t whiteGain, uint16_t resisterOhms) : + extROhms(resisterOhms) + { + redGain &= 0x0f; + greenGain &= 0x0f; + blueGain &= 0x0f; + whiteGain &= 0x0f; + + RedTenthMilliAmpere = calcCurrent(extROhms, redGain); + GreenTenthMilliAmpere = calcCurrent(extROhms, greenGain); + BlueTenthMilliAmpere = calcCurrent(extROhms, blueGain); + WhiteTenthMilliAmpere = calcCurrent(extROhms, whiteGain); + + // RGBW 4 bits each + Encoded = redGain << 12 | greenGain << 8 | blueGain << 4 | whiteGain; + } + +protected: + const uint16_t extROhms; + + static uint16_t calcCurrent(const uint16_t ohms, const uint8_t gain) + { + uint16_t mA = (1100 / ohms * (240 + (gain * 32))); // from spec sheet, gain 0-15 instead + return mA * 10; // return tenths of mA + } + +}; + +template class NeoRgbwSm168x4Elements : public Neo4ByteElements +{ +public: + typedef T_SETTINGS SettingsObject; static const size_t SettingsSize = 2; static void applySettings([[maybe_unused]] uint8_t* pData, [[maybe_unused]] size_t sizeData, [[maybe_unused]] const SettingsObject& settings) { // settings are at the end of the data stream - uint8_t* pSet = pData + sizeData - SettingsSize; - - // four bits per element in RGBW order - *pSet++ = ((SettingsObject::LimitCurrent(settings.RedTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor) << 4 | - ((SettingsObject::LimitCurrent(settings.GreenTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor); - *pSet++ = ((SettingsObject::LimitCurrent(settings.BlueTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor) << 4 | - ((SettingsObject::LimitCurrent(settings.WhiteCurrent) - SettingsObject::MinCurrent) / EncodeDivisor); + uint16_t* pSet = reinterpret_cast(pData + sizeData - SettingsSize); + *pSet = settings.Encoded; } static uint8_t* pixels([[maybe_unused]] uint8_t* pData, [[maybe_unused]] size_t sizeData) @@ -82,12 +189,7 @@ public: { return pData; } -}; - -class NeoRgbwSm168xxFeature : public Neo4ByteElementsSm168xxSettings -{ -public: static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) { uint8_t* p = getPixelAddress(pPixels, indexPixel); @@ -110,7 +212,7 @@ public: return color; } - + static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel) { ColorObject color; @@ -123,6 +225,69 @@ public: return color; } - }; +template class NeoRgbSm168x3Elements : public Neo3ByteElements +{ +public: + typedef T_SETTINGS SettingsObject; + static const size_t SettingsSize = 2; + + static void applySettings([[maybe_unused]] uint8_t* pData, [[maybe_unused]] size_t sizeData, [[maybe_unused]] const SettingsObject& settings) + { + // settings are at the end of the data stream + uint16_t* pSet = reinterpret_cast(pData + sizeData - SettingsSize); + + *pSet = settings.Encoded; + } + + static uint8_t* pixels([[maybe_unused]] uint8_t* pData, [[maybe_unused]] size_t sizeData) + { + return pData; + } + + static const uint8_t* pixels([[maybe_unused]] const uint8_t* pData, [[maybe_unused]] size_t sizeData) + { + return pData; + } + + static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) + { + uint8_t* p = getPixelAddress(pPixels, indexPixel); + + *p++ = color.R; + *p++ = color.G; + *p = color.B; + } + + static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint8_t* p = getPixelAddress(pPixels, indexPixel); + + color.R = *p++; + color.G = *p++; + color.B = *p; + + 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.R = pgm_read_byte(p++); + color.G = pgm_read_byte(p++); + color.B = pgm_read_byte(p); + + return color; + } +}; + +typedef NeoRgbSm168x3Elements NeoRgbSm16803pbColorFeature; +typedef NeoRgbSm168x3Elements NeoRgbSm16823eColorFeature; +typedef NeoRgbwSm168x4Elements NeoRgbwSm16804ebColorFeature; +typedef NeoRgbwSm168x4Elements NeoRgbwSm16824eColorFeature; + + diff --git a/src/internal/NeoTm1814ColorFeatures.h b/src/internal/NeoTm1814ColorFeatures.h index 8fa181c..674c4d1 100644 --- a/src/internal/NeoTm1814ColorFeatures.h +++ b/src/internal/NeoTm1814ColorFeatures.h @@ -66,7 +66,7 @@ public: uint8_t* pSet = pData; // C1 - *pSet++ = (SettingsObject::LimitCurrent(settings.WhiteCurrent) - SettingsObject::MinCurrent) / EncodeDivisor; + *pSet++ = (SettingsObject::LimitCurrent(settings.WhiteTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor; *pSet++ = (SettingsObject::LimitCurrent(settings.RedTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor; *pSet++ = (SettingsObject::LimitCurrent(settings.GreenTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor; *pSet++ = (SettingsObject::LimitCurrent(settings.BlueTenthMilliAmpere) - SettingsObject::MinCurrent) / EncodeDivisor; diff --git a/src/internal/Rgbw64Color.h b/src/internal/Rgbw64Color.h index 100c520..218282a 100644 --- a/src/internal/Rgbw64Color.h +++ b/src/internal/Rgbw64Color.h @@ -207,7 +207,7 @@ struct Rgbw64Color total += R * settings.RedTenthMilliAmpere / Max; total += G * settings.GreenTenthMilliAmpere / Max; total += B * settings.BlueTenthMilliAmpere / Max; - total += W * settings.WhiteCurrent / Max; + total += W * settings.WhiteTenthMilliAmpere / Max; return total; } diff --git a/src/internal/RgbwColor.h b/src/internal/RgbwColor.h index 6fdc73c..2bc7b70 100644 --- a/src/internal/RgbwColor.h +++ b/src/internal/RgbwColor.h @@ -190,7 +190,7 @@ struct RgbwColor total += R * settings.RedTenthMilliAmpere / Max; total += G * settings.GreenTenthMilliAmpere / Max; total += B * settings.BlueTenthMilliAmpere / Max; - total += W * settings.WhiteCurrent / Max; + total += W * settings.WhiteTenthMilliAmpere / Max; return total; }