Skip to content

Implemented 16Bit HD108-Leds in HyperionNG #1826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 5 additions & 1 deletion assets/webconfig/js/content_leds.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var bottomRight2bottomLeft = null;
var bottomLeft2topLeft = null;
var toggleKeystoneCorrectionArea = false;

var devSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'sk9822', 'ws2812spi'];
var devSPI = ['apa102', 'apa104', 'hd108', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'sk9822', 'ws2801', 'ws2812spi'];
var devFTDI = ['apa102_ftdi', 'sk6812_ftdi', 'ws2812_ftdi'];
var devRPiPWM = ['ws281x'];
var devRPiGPIO = ['piblaster'];
Expand Down Expand Up @@ -1115,6 +1115,7 @@ $(document).ready(function () {
case "ws2812spi":
case "piblaster":
case "ws281x":
case "hd108":

//Serial devices
case "adalight":
Expand Down Expand Up @@ -1480,6 +1481,7 @@ $(document).ready(function () {
case "apa102_ftdi":
case "sk6812_ftdi":
case "ws2812_ftdi":
case "hd108":
default:
}

Expand Down Expand Up @@ -1962,6 +1964,7 @@ function saveLedConfig(genDefLayout = false) {
case "apa102_ftdi":
case "sk6812_ftdi":
case "ws2812_ftdi":
case "hd108":
default:
if (genDefLayout === true) {
ledConfig = {
Expand Down Expand Up @@ -2219,6 +2222,7 @@ var updateOutputSelectList = function (ledType, discoveryInfo) {
case "sk6822spi":
case "sk9822":
case "ws2812spi":
case "hd108":
case "piblaster":
for (const device of discoveryInfo.devices) {
enumVals.push(device.systemLocation);
Expand Down
3 changes: 2 additions & 1 deletion libsrc/leddevice/LedDeviceSchemas.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<file alias="schema-ws2812_ftdi">schemas/schema-ws2812_ftdi.json</file>
<file alias="schema-apa102_ftdi">schemas/schema-apa102_ftdi.json</file>
<file alias="schema-sk6812_ftdi">schemas/schema-sk6812_ftdi.json</file>
<file alias="schema-skydimo">schemas/schema-skydimo.json</file>
<file alias="schema-skydimo">schemas/schema-skydimo.json</file>
<file alias="schema-hd108">schemas/schema-hd108.json</file>
</qresource>
</RCC>
73 changes: 73 additions & 0 deletions libsrc/leddevice/dev_spi/LedDeviceHD108.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "LedDeviceHD108.h"

// Constructor
LedDeviceHD108::LedDeviceHD108(const QJsonObject &deviceConfig)
: ProviderSpi(deviceConfig)
{
// Overwrite non supported/required features
_latchTime_ms = 0;
// Initialize _global_brightness
_global_brightness = 0xFFFF;
}

LedDevice* LedDeviceHD108::construct(const QJsonObject &deviceConfig)
{
return new LedDeviceHD108(deviceConfig);
}

// Initialization method
bool LedDeviceHD108::init(const QJsonObject &deviceConfig)
{
bool isInitOK = false;

if ( ProviderSpi::init(deviceConfig) )
{
_brightnessControlMaxLevel = deviceConfig["brightnessControlMaxLevel"].toInt(HD108_BRIGHTNESS_MAX_LEVEL);
Info(_log, "[%s] Setting maximum brightness to [%d] = %d%%", QSTRING_CSTR(_activeDeviceType), _brightnessControlMaxLevel, _brightnessControlMaxLevel * 100 / HD108_BRIGHTNESS_MAX_LEVEL);

// Set the global brightness or control byte based on the provided formula
_global_brightness = (1 << 15) | (_brightnessControlMaxLevel << 10) | (_brightnessControlMaxLevel << 5) | _brightnessControlMaxLevel;

isInitOK = true;
}

return isInitOK;
}

// Write method to update the LED colors
int LedDeviceHD108::write(const std::vector<ColorRgb> & ledValues)
{
std::vector<uint8_t> hd108Data;

// Start frame - 64 bits of 0 (8 bytes of 0)
hd108Data.insert(hd108Data.end(), 8, 0x00);

// Adapted logic from your HD108 library's "show" and "setPixelColor8Bit" methods
for (const ColorRgb &color : ledValues)
{
// Convert 8-bit to 16-bit colors
uint16_t red16 = (color.red << 8) | color.red;
uint16_t green16 = (color.green << 8) | color.green;
uint16_t blue16 = (color.blue << 8) | color.blue;

// Push global and color components into hd108Data
// Brightness
hd108Data.push_back(_global_brightness >> 8);
hd108Data.push_back(_global_brightness & 0xFF);
// Color - Red
hd108Data.push_back(red16 >> 8);
hd108Data.push_back(red16 & 0xFF);
// Color - Green
hd108Data.push_back(green16 >> 8);
hd108Data.push_back(green16 & 0xFF);
// Color - Blue
hd108Data.push_back(blue16 >> 8);
hd108Data.push_back(blue16 & 0xFF);
}

// End frame - write "1"s equal to at least how many pixels are in the string
hd108Data.insert(hd108Data.end(), ledValues.size() / 16 + 1, 0xFF);

// Use ProviderSpi's writeBytes method to send the data
return writeBytes(hd108Data.size(), hd108Data.data());
}
53 changes: 53 additions & 0 deletions libsrc/leddevice/dev_spi/LedDeviceHD108.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef LEDDEVICEHD108_H
#define LEDDEVICEHD108_H

#include "ProviderSpi.h"

/// The maximal level supported by the HD108 brightness control field, 31
const int HD108_BRIGHTNESS_MAX_LEVEL = 31;


class LedDeviceHD108 : public ProviderSpi
{

public:

///
/// @brief Constructs an HD108 LED-device
///
/// @param deviceConfig Device's configuration as JSON-Object
///
explicit LedDeviceHD108(const QJsonObject &deviceConfig);

///
/// @brief Constructs the LED-device
///
/// @param[in] deviceConfig Device's configuration as JSON-Object
/// @return LedDevice constructed
///
static LedDevice* construct(const QJsonObject &deviceConfig);

private:

///
/// @brief Initialise the device's configuration
///
/// @param[in] deviceConfig the JSON device configuration
/// @return True, if success
///
bool init(const QJsonObject &deviceConfig) override;

///
/// @brief Writes the RGB-Color values to the LEDs.
///
/// @param[in] ledValues The RGB-color per LED
/// @return Zero on success, else negative
///
int write(const std::vector<ColorRgb> & ledValues) override;

/// The brighness level. Possibile values 1 .. 31.
int _brightnessControlMaxLevel;
uint16_t _global_brightness;
};

#endif // LEDDEVICEHD108_H
41 changes: 41 additions & 0 deletions libsrc/leddevice/schemas/schema-hd108.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"type":"object",
"required":true,
"properties":{
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"propertyOrder" : 1
},
"rate": {
"type": "integer",
"title":"edt_dev_spec_baudrate_title",
"default": 1000000,
"propertyOrder" : 2
},
"invert": {
"type": "boolean",
"title":"edt_dev_spec_invert_title",
"default": false,
"propertyOrder" : 3
},
"brightnessControlMaxLevel": {
"type": "integer",
"title":"edt_conf_color_brightness_title",
"default": 31,
"minimum": 1,
"maximum": 31,
"propertyOrder" : 4
},
"rewriteTime": {
"type": "integer",
"title":"edt_dev_general_rewriteTime_title",
"default": 0,
"append" : "edt_append_ms",
"minimum": 0,
"access" : "expert",
"propertyOrder" : 5
}
},
"additionalProperties": true
}
Loading