Skip to content

Commit

Permalink
Merge pull request #1028 from Duet3D/3.5-dev-DotStarConfig
Browse files Browse the repository at this point in the history
3.5-dev-DotStarConfig
  • Loading branch information
dc42 authored Aug 27, 2024
2 parents b4675af + fdd77b8 commit c53aa8e
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 5 deletions.
124 changes: 119 additions & 5 deletions src/LedStrips/DotStarLedStrip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
*/

#include <LedStrips/DotStarLedStrip.h>
#include <GCodes/GCodeBuffer/GCodeBuffer.h>

#if SUPPORT_REMOTE_COMMANDS
# include <CanMessageGenericParser.h>
#endif

#if SUPPORT_LED_STRIPS && SUPPORT_DMA_DOTSTAR

DotStarLedStrip::DotStarLedStrip() noexcept
: LocalLedStrip(LedStripType::DotStar, DefaultDotStarSpiClockFrequency)
: LocalLedStrip(LedStripType::DotStar, DefaultDotStarSpiClockFrequency), colorOrder(ColorOrder::BGR)
{
}

Expand All @@ -19,6 +24,14 @@ GCodeResult DotStarLedStrip::Configure(GCodeBuffer& gb, const StringRef& reply,
{
bool seen = false;
GCodeResult rslt = CommonConfigure(gb, reply, pinName, seen);

if (gb.Seen('K'))
{
uint32_t order;
gb.TryGetLimitedUIValue('K', order, seen, (uint32_t)ColorOrder::count);
colorOrder = (ColorOrder)order;
}

if (seen)
{
if (!UsesDma())
Expand All @@ -39,6 +52,19 @@ GCodeResult DotStarLedStrip::Configure(CanMessageGenericParser& parser, const St
{
bool seen = false;
GCodeResult rslt = CommonConfigure(parser, reply, seen, extra);

uint32_t order;
if (parser.GetUintParam('K', order))
{
if (order >= (uint32_t)ColorOrder::count)
{
reply.printf("Invalid color order K=%lu", order);
return GCodeResult::warning;
}
colorOrder = (ColorOrder)order;
seen = true;
}

if (seen)
{
if (!UsesDma())
Expand Down Expand Up @@ -73,11 +99,55 @@ GCodeResult DotStarLedStrip::HandleM150(CanMessageGenericParser& parser, const S
params.numLeds = numRemaining;
}

uint32_t data;
# if USE_16BIT_SPI
// Swap bytes for 16-bit SPI
const uint32_t data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.green & 255) << 24) | ((params.red & 255) << 16);
switch (colorOrder)
{
case ColorOrder::BRG:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.red & 255) << 24) | ((params.green & 255) << 16);
break;
case ColorOrder::RGB:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.red & 255)) | ((params.green & 255) << 24) | ((params.blue & 255) << 16);
break;
case ColorOrder::GRB: // no idea why but RBG and GRB behave the wrong way round in testing with 2 different LED strips so have just swapped them so it works in practice.
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.red & 255)) | ((params.blue & 255) << 24) | ((params.green & 255) << 16);
break;
case ColorOrder::GBR:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.green & 255)) | ((params.blue & 255) << 24) | ((params.red & 255) << 16);
break;
case ColorOrder::RBG: // see above note about GRB
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.green & 255)) | ((params.red & 255) << 24) | ((params.blue & 255) << 16);
break;
case ColorOrder::BGR:
default:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.green & 255) << 24) | ((params.red & 255) << 16);
break;
}
# else
const uint32_t data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.green & 255) << 16) | ((params.red & 255) << 24);
// Untested, might suffer from same RBG/GRB issue as above
switch (colorOrder)
{
case ColorOrder::BRG:
data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.red & 255) << 16) | ((params.green & 255) << 24);
break;
case ColorOrder::RGB:
data = (params.brightness >> 3) | 0xE0 | ((params.red & 255) << 8) | ((params.green & 255) << 16) | ((params.blue & 255) << 24);
break;
case ColorOrder::RBG:
data = (params.brightness >> 3) | 0xE0 | ((params.red & 255) << 8) | ((params.blue & 255) << 16) | ((params.green & 255) << 24);
break;
case ColorOrder::GBR:
data = (params.brightness >> 3) | 0xE0 | ((params.green & 255) << 8) | ((params.blue & 255) << 16) | ((params.red & 255) << 24);
break;
case ColorOrder::GRB:
data = (params.brightness >> 3) | 0xE0 | ((params.green & 255) << 8) | ((params.red & 255) << 16) | ((params.blue & 255) << 24);
break;
case ColorOrder::BGR:
default:
data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.green & 255) << 16) | ((params.red & 255) << 24);
break;
}
# endif
return SendDotStarData(data, params.numLeds, params.following);
}
Expand Down Expand Up @@ -105,11 +175,55 @@ GCodeResult DotStarLedStrip::HandleM150(GCodeBuffer &gb, const StringRef &reply)
params.numLeds = numRemaining;
}

uint32_t data;
# if USE_16BIT_SPI
// Swap bytes for 16-bit SPI
const uint32_t data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.green & 255) << 24) | ((params.red & 255) << 16);
switch (colorOrder)
{
case ColorOrder::BRG:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.red & 255) << 24) | ((params.green & 255) << 16);
break;
case ColorOrder::RGB:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.red & 255)) | ((params.green & 255) << 24) | ((params.blue & 255) << 16);
break;
case ColorOrder::GRB: // no idea why but RBG and GRB behave the wrong way round in testing with 2 different LED strips so have just swapped them so it works in practice.
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.red & 255)) | ((params.blue & 255) << 24) | ((params.green & 255) << 16);
break;
case ColorOrder::GBR:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.green & 255)) | ((params.blue & 255) << 24) | ((params.red & 255) << 16);
break;
case ColorOrder::RBG: // see above note about GRB
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.green & 255)) | ((params.red & 255) << 24) | ((params.blue & 255) << 16);
break;
case ColorOrder::BGR:
default:
data = ((params.brightness & 0xF8) << 5) | (0xE0 << 8) | ((params.blue & 255)) | ((params.green & 255) << 24) | ((params.red & 255) << 16);
break;
}
# else
const uint32_t data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.green & 255) << 16) | ((params.red & 255) << 24);
// Untested, might suffer from same RBG/GRB issue as above
switch (colorOrder)
{
case ColorOrder::BRG:
data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.red & 255) << 16) | ((params.green & 255) << 24);
break;
case ColorOrder::RGB:
data = (params.brightness >> 3) | 0xE0 | ((params.red & 255) << 8) | ((params.green & 255) << 16) | ((params.blue & 255) << 24);
break;
case ColorOrder::RBG:
data = (params.brightness >> 3) | 0xE0 | ((params.red & 255) << 8) | ((params.blue & 255) << 16) | ((params.green & 255) << 24);
break;
case ColorOrder::GBR:
data = (params.brightness >> 3) | 0xE0 | ((params.green & 255) << 8) | ((params.blue & 255) << 16) | ((params.red & 255) << 24);
break;
case ColorOrder::GRB:
data = (params.brightness >> 3) | 0xE0 | ((params.green & 255) << 8) | ((params.red & 255) << 16) | ((params.blue & 255) << 24);
break;
case ColorOrder::BGR:
default:
data = (params.brightness >> 3) | 0xE0 | ((params.blue & 255) << 8) | ((params.green & 255) << 16) | ((params.red & 255) << 24);
break;
}
# endif
return SendDotStarData(data, params.numLeds, params.following);
}
Expand Down
12 changes: 12 additions & 0 deletions src/LedStrips/DotStarLedStrip.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
class DotStarLedStrip : public LocalLedStrip
{
public:
enum class ColorOrder : uint8_t
{
BGR = 0,
BRG,
RGB,
RBG,
GBR,
GRB,
count
};

DotStarLedStrip() noexcept;

GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, const char *_ecv_array pinName) THROWS(GCodeException) override;
Expand All @@ -36,6 +47,7 @@ class DotStarLedStrip : public LocalLedStrip
unsigned int numRemaining = 0; // how much of the current request remains after the current transfer
unsigned int totalSent = 0; // total amount of data sent since the start frame
bool needStartFrame = true;
ColorOrder colorOrder;
};

#endif
Expand Down

0 comments on commit c53aa8e

Please sign in to comment.