Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 19 additions & 49 deletions src/PixelcadeDMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
namespace DMDUtil
{

PixelcadeDMD::PixelcadeDMD(struct sp_port* pSerialPort, int width, int height, bool colorSwap, bool isV2,
int firmwareVersion)
PixelcadeDMD::PixelcadeDMD(struct sp_port* pSerialPort, int width, int height, bool colorSwap, bool isV2)
{
m_pSerialPort = pSerialPort;
m_width = width;
m_height = height;
m_colorSwap = colorSwap;
m_isV2 = isV2;
m_firmwareVersion = firmwareVersion;
m_length = width * height;
m_pThread = nullptr;
m_running = false;
Expand Down Expand Up @@ -172,7 +170,15 @@ PixelcadeDMD* PixelcadeDMD::Open(const char* pDevice)
"ColorSwap=%d",
pDevice, hardwareId, bootloaderId, firmware, width, height, isV2, firmwareVersion, colorSwap);

return new PixelcadeDMD(pSerialPort, width, height, colorSwap, isV2, firmwareVersion);
if (isV2 && firmwareVersion < 23)
{
Log(DMDUtil_LogLevel_INFO, "Pixelcade: V2 firmware %d is not supported, v23 or later is required", firmwareVersion);
sp_close(pSerialPort);
sp_free_port(pSerialPort);
return nullptr;
}

return new PixelcadeDMD(pSerialPort, width, height, colorSwap, isV2);
}

void PixelcadeDMD::Update(uint16_t* pData)
Expand Down Expand Up @@ -227,40 +233,14 @@ int PixelcadeDMD::BuildFrame(uint8_t* pFrameBuffer, size_t bufferSize, uint8_t c
return frameSize;
}

int PixelcadeDMD::BuildRawCommand(uint8_t* pFrameBuffer, size_t bufferSize, uint8_t command, const uint8_t* pData,
uint16_t dataLength)
{
const size_t commandSize = 1 + dataLength;

if (commandSize > bufferSize || dataLength > PIXELCADE_MAX_DATA_SIZE) return -1;

pFrameBuffer[0] = command;

if (dataLength > 0 && pData) memcpy(pFrameBuffer + 1, pData, dataLength);

return commandSize;
}

void PixelcadeDMD::EnableRgbLedMatrix(int shifterLen32, int rows)
{
uint8_t configData = (uint8_t)((shifterLen32 & 0x0F) | ((rows == 8 ? 0 : 1) << 4));

if (m_isV2)
{
uint8_t command =
(m_firmwareVersion >= 23) ? PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE_V23 : PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE;
uint8_t frame[8];
int frameSize;

if (m_firmwareVersion >= 23)
{
frameSize = BuildFrame(frame, sizeof(frame), command, &configData, 1);
}
else
{
frameSize = BuildRawCommand(frame, sizeof(frame), command, &configData, 1);
}

int frameSize = BuildFrame(frame, sizeof(frame), PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE_V2, &configData, 1);
if (frameSize > 0) sp_blocking_write(m_pSerialPort, frame, frameSize, 0);
}
else
Expand All @@ -281,9 +261,9 @@ void PixelcadeDMD::Run()
{
Log(DMDUtil_LogLevel_INFO, "PixelcadeDMD run thread starting");

if (m_firmwareVersion >= 23)
if (m_isV2)
{
uint8_t initCmd = PIXELCADE_COMMAND_V23_INIT;
uint8_t initCmd = PIXELCADE_COMMAND_INIT_V2;
sp_blocking_write(m_pSerialPort, &initCmd, 1, 0);
}

Expand All @@ -292,8 +272,7 @@ void PixelcadeDMD::Run()
EnableRgbLedMatrix(shifterLen32, rows);

int errors = 0;
FrameUtil::ColorMatrix colorMatrix =
(!m_colorSwap) ? FrameUtil::ColorMatrix::Rgb : FrameUtil::ColorMatrix::Rbg;
FrameUtil::ColorMatrix colorMatrix = (!m_colorSwap) ? FrameUtil::ColorMatrix::Rgb : FrameUtil::ColorMatrix::Rbg;

const int maxFrameDataSize = m_length * 3;
uint8_t* pFrameData = new uint8_t[maxFrameDataSize + 10];
Expand Down Expand Up @@ -337,17 +316,8 @@ void PixelcadeDMD::Run()
payloadSize = m_length * 3;
}

int frameSize;
if (m_firmwareVersion >= 23)
{
memcpy(pFrameData + 5, frame.pData, payloadSize);
frameSize = BuildFrame(pFrameData, maxFrameDataSize + 10, command, pFrameData + 5, payloadSize);
}
else
{
memcpy(pFrameData + 1, frame.pData, payloadSize);
frameSize = BuildRawCommand(pFrameData, maxFrameDataSize + 10, command, pFrameData + 1, payloadSize);
}
memcpy(pFrameData + 5, frame.pData, payloadSize);
int frameSize = BuildFrame(pFrameData, maxFrameDataSize + 10, command, pFrameData + 5, payloadSize);

if (frameSize > 0)
response = sp_blocking_write(m_pSerialPort, pFrameData, frameSize, PIXELCADE_COMMAND_WRITE_TIMEOUT);
Expand All @@ -357,8 +327,8 @@ void PixelcadeDMD::Run()
command = PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME;
payloadSize = m_length * 3 / 2;
pFrameData[0] = command;
FrameUtil::Helper::SplitIntoRgbPlanes((uint16_t*)frame.pData, m_length, m_width, rows / 2,
pFrameData + 1, colorMatrix);
FrameUtil::Helper::SplitIntoRgbPlanes((uint16_t*)frame.pData, m_length, m_width, rows / 2, pFrameData + 1,
colorMatrix);
response = sp_blocking_write(m_pSerialPort, pFrameData, 1 + payloadSize, PIXELCADE_COMMAND_WRITE_TIMEOUT);
}

Expand Down Expand Up @@ -413,4 +383,4 @@ void PixelcadeDMD::Run()
});
}

} // namespace DMDUtil
} // namespace DMDUtil
12 changes: 4 additions & 8 deletions src/PixelcadeDMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
#define PIXELCADE_RESPONSE_ESTABLE_CONNECTION 0x00
#define PIXELCADE_COMMAND_RGB_LED_MATRIX_FRAME 0x1F
#define PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE 0x1E
#define PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE_V23 0x2E //For Pixelcade V2 boards with firwmare v23 or later
#define PIXELCADE_COMMAND_V23_INIT 0xEF //one time init command for Pixelcade V2 boards with V23+ firmware to set up the framing protocol
#define PIXELCADE_COMMAND_RGB_LED_MATRIX_ENABLE_V2 0x2E
#define PIXELCADE_COMMAND_INIT_V2 0xEF
#define PIXELCADE_COMMAND_RGB565 0x30
#define PIXELCADE_COMMAND_RGB888 0x40
#define PIXELCADE_FRAME_START_MARKER 0xFE
Expand Down Expand Up @@ -46,7 +46,7 @@ struct PixelcadeFrame
class PixelcadeDMD
{
public:
PixelcadeDMD(struct sp_port* pSerialPort, int width, int height, bool colorSwap, bool isV2, int firmwareVersion);
PixelcadeDMD(struct sp_port* pSerialPort, int width, int height, bool colorSwap, bool isV2);
~PixelcadeDMD();

static PixelcadeDMD* Connect(const char* pDevice = nullptr);
Expand All @@ -56,22 +56,18 @@ class PixelcadeDMD
int GetWidth() const { return m_width; }
int GetHeight() const { return m_height; }
bool GetIsV2() const { return m_isV2; }
int GetFirmwareVersion() const { return m_firmwareVersion; }

private:
static PixelcadeDMD* Open(const char* pDevice);
void Run();
void EnableRgbLedMatrix(int shifterLen32, int rows);
int BuildFrame(uint8_t* pFrameBuffer, size_t bufferSize, uint8_t command, const uint8_t* pData, uint16_t dataLength);
int BuildRawCommand(uint8_t* pFrameBuffer, size_t bufferSize, uint8_t command, const uint8_t* pData,
uint16_t dataLength);

struct sp_port* m_pSerialPort;
int m_width;
int m_height;
bool m_colorSwap;
bool m_isV2;
int m_firmwareVersion;
int m_length;

std::thread* m_pThread;
Expand All @@ -80,4 +76,4 @@ class PixelcadeDMD
bool m_running;
};

} // namespace DMDUtil
} // namespace DMDUtil