diff --git a/firmware-template-gd32/lib/Rules.mk b/firmware-template-gd32/lib/Rules.mk index 518899f..6831c0f 100644 --- a/firmware-template-gd32/lib/Rules.mk +++ b/firmware-template-gd32/lib/Rules.mk @@ -28,6 +28,9 @@ include ../firmware-template-gd32/Includes.mk DEFINES:=$(addprefix -D,$(DEFINES)) DEFINES+=-D_TIME_STAMP_YEAR_=$(shell date +"%Y") -D_TIME_STAMP_MONTH_=$(shell date +"%-m") -D_TIME_STAMP_DAY_=$(shell date +"%-d") DEFINES+=-DCONFIG_STORE_USE_ROM +DEFINES+=-DDISABLE_FS +DEFINES+=-DENABLE_RDM_MANUFACTURER_PIDS +DEFINES+=-DENABLE_CONFIG_PIDS COPS=-DBARE_METAL -DGD32 -DGD32F30X_HD -D$(MCU) -D$(BOARD) COPS+=$(DEFINES) $(MAKE_FLAGS) $(INCLUDES) diff --git a/gd32_dmx_usb_pro/.settings/language.settings.xml b/gd32_dmx_usb_pro/.settings/language.settings.xml index 698395a..9676c01 100755 --- a/gd32_dmx_usb_pro/.settings/language.settings.xml +++ b/gd32_dmx_usb_pro/.settings/language.settings.xml @@ -2,7 +2,10 @@ - + + + + diff --git a/gd32_rdm_responder/.cproject b/gd32_rdm_responder/.cproject index 4e452d1..2791779 100644 --- a/gd32_rdm_responder/.cproject +++ b/gd32_rdm_responder/.cproject @@ -101,6 +101,7 @@ @@ -153,6 +156,8 @@ + + diff --git a/gd32_rdm_responder/.project b/gd32_rdm_responder/.project index 6bb46e3..6c463fc 100644 --- a/gd32_rdm_responder/.project +++ b/gd32_rdm_responder/.project @@ -3,6 +3,29 @@ gd32_rdm_responder + lib-c + lib-c++ + lib-configstore + lib-debug + lib-device + lib-display + lib-displayudf + lib-dmx + lib-dmxreceiver + lib-flashcode + lib-gd32 + lib-hal + lib-lightset + lib-network + lib-properties + lib-rdm + lib-rdmresponder + lib-rdmsensor + lib-rdmsubdevice + lib-usb + lib-widget + lib-ws28xx + lib-ws28xxdmx diff --git a/gd32_rdm_responder/.settings/language.settings.xml b/gd32_rdm_responder/.settings/language.settings.xml index d0a369d..833c56d 100644 --- a/gd32_rdm_responder/.settings/language.settings.xml +++ b/gd32_rdm_responder/.settings/language.settings.xml @@ -2,7 +2,10 @@ - + + + + diff --git a/gd32_rdm_responder/.settings/org.eclipse.cdt.core.prefs b/gd32_rdm_responder/.settings/org.eclipse.cdt.core.prefs index c8ec5df..e563d1a 100644 --- a/gd32_rdm_responder/.settings/org.eclipse.cdt.core.prefs +++ b/gd32_rdm_responder/.settings/org.eclipse.cdt.core.prefs @@ -4,3 +4,5 @@ doxygen/doxygen_use_javadoc_tags=true doxygen/doxygen_use_pre_tag=false doxygen/doxygen_use_structural_commands=false eclipse.preferences.version=1 +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1766002374.1447165843/append=true +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1766002374.1447165843/appendContributed=true diff --git a/gd32_rdm_responder/Makefile.GD32 b/gd32_rdm_responder/Makefile.GD32 index ccc485b..46a569f 100644 --- a/gd32_rdm_responder/Makefile.GD32 +++ b/gd32_rdm_responder/Makefile.GD32 @@ -5,6 +5,9 @@ DEFINES+=ENABLE_RDM_SELF_TEST DEFINES+=OUTPUT_DMX_PIXEL DEFINES+=CONFIG_PIXELDMX_MAX_PORTS=1 +DEFINES+=ENABLE_RDM_MANUFACTURER_PIDS +DEFINES+=ENABLE_CONFIG_PIDS + DEFINES+=USE_SPI_DMA DEFINES+=DISPLAY_UDF diff --git a/gd32_rdm_responder/firmware/main.cpp b/gd32_rdm_responder/firmware/main.cpp index 84030e7..8498547 100644 --- a/gd32_rdm_responder/firmware/main.cpp +++ b/gd32_rdm_responder/firmware/main.cpp @@ -23,6 +23,7 @@ * THE SOFTWARE. */ +#include #include #include @@ -42,6 +43,7 @@ #if defined (ENABLE_RDM_SUBDEVICES) # include "rdmsubdevicesparams.h" #endif +#include "personalities.h" #include "pixeldmxparams.h" #include "ws28xxdmx.h" @@ -97,8 +99,8 @@ void main() { PixelDmxConfiguration pixelDmxConfiguration; - StorePixelDmx storePixelDmx; - PixelDmxParams pixelDmxParams(&storePixelDmx); + auto storePixelDmx = StorePixelDmx::Get(); + PixelDmxParams pixelDmxParams(storePixelDmx); if (pixelDmxParams.Load()) { pixelDmxParams.Dump(); @@ -125,8 +127,8 @@ void main() { pixelDmxConfiguration.SetCount(nCount); } - WS28xxDmx pixelDmx(pixelDmxConfiguration); - pixelDmx.SetWS28xxDmxStore(&storePixelDmx); + WS28xxDmx pixelDmx(pixelDmxConfiguration, storePixelDmx); + pixelDmx.SetWS28xxDmxStore(storePixelDmx); PixelDmxStartStop pixelDmxStartStop; pixelDmx.SetPixelDmxHandler(&pixelDmxStartStop); @@ -134,8 +136,19 @@ void main() { const auto nTestPattern = static_cast(pixelDmxParams.GetTestPattern()); PixelTestPattern pixelTestPattern(nTestPattern, 1); - PixelDmxParamsRdm pixelDmxParamsRdm(&storePixelDmx); - + PixelDmxParamsRdm pixelDmxParamsRdm(storePixelDmx); + + RDMPersonality *personalities[PERSONALITY_COUNT]; +#if defined(ENABLE_CONFIG_PIDS) + static_assert( + PERSONALITY_COUNT == static_cast(pixel::Type::UNDEFINED), + "Personality Count != Pixel Type Count"); + for (auto n = 0; n < PERSONALITY_COUNT; ++n) + { + const auto description = PixelType::GetType(static_cast(n)); + personalities[n] = new RDMPersonality(description, &pixelDmx); + } +#else char aDescription[rdm::personality::DESCRIPTION_MAX_LENGTH]; snprintf(aDescription, sizeof(aDescription) - 1U, "%s:%u G%u [%s]", PixelType::GetType(pixelDmxConfiguration.GetType()), @@ -143,9 +156,10 @@ void main() { pixelDmxConfiguration.GetGroupingCount(), PixelType::GetMap(pixelDmxConfiguration.GetMap())); - RDMPersonality *personalities[2] = { new RDMPersonality(aDescription, &pixelDmx), new RDMPersonality("Config mode", &pixelDmxParamsRdm) }; - - RDMResponder rdmResponder(personalities, 2); + personalities[static_cast(Personalities::DEFAULT)] = new RDMPersonality(aDescription, &pixelDmx); + personalities[static_cast(Personalities::CONFIG_MODE)] = new RDMPersonality("Config mode", &pixelDmxParamsRdm) +#endif + RDMResponder rdmResponder(personalities, PERSONALITY_COUNT); rdmResponder.SetProductCategory(E120_PRODUCT_CATEGORY_FIXTURE); rdmResponder.SetProductDetail(E120_PRODUCT_DETAIL_LED); @@ -183,6 +197,11 @@ void main() { rdmResponder.DmxDisableOutput(!isConfigMode && (nTestPattern != pixelpatterns::Pattern::NONE)); rdmResponder.Print(); +#if defined(ENABLE_CONFIG_PIDS) + const auto nPersonality = Personalities::toPersonalityIdx(Personalities::fromPixelType(pixelDmx.GetType())); + rdmResponder.SetPersonalityCurrent(RDM_ROOT_DEVICE, nPersonality); +#endif + if (isConfigMode) { pixelDmxParamsRdm.Print(); } else { diff --git a/gd32_rdm_responder/include/personalities.h b/gd32_rdm_responder/include/personalities.h new file mode 100644 index 0000000..7e0d12d --- /dev/null +++ b/gd32_rdm_responder/include/personalities.h @@ -0,0 +1,52 @@ +/* + * personalities.h + * + * Created on: 20 Nov 2023 + * Author: marcusbirkin + */ + +#ifndef INCLUDE_PERSONALITIES_H_ +#define INCLUDE_PERSONALITIES_H_ + +#include +#include + +#include "pixeltype.h" + +namespace Personalities +{ + +enum class Personality : uint8_t { +#if defined(ENABLE_CONFIG_PIDS) + WS2801, + WS2811, + WS2812, + WS2812B, + WS2813, + WS2815, + SK6812, + SK6812W, + UCS1903, + UCS2903, + CS8812, + APA102, + SK9822, + P9813, +#else + DEFAULT, + CONFIG_MODE, +#endif + // Last item + COUNT +}; +#define PERSONALITY_COUNT static_cast::type>(Personalities::Personality::COUNT) + +uint8_t toPersonalityIdx(Personality personality); +Personality fromPersonalityIdx(uint8_t nPersonality); + +pixel::Type toPixelType(Personality personality); +Personality fromPixelType(pixel::Type type); + +} // namespace Personalities + +#endif /* INCLUDE_PERSONALITIES_H_ */ diff --git a/gd32_rdm_responder/lib/personalities.cpp b/gd32_rdm_responder/lib/personalities.cpp new file mode 100644 index 0000000..df28371 --- /dev/null +++ b/gd32_rdm_responder/lib/personalities.cpp @@ -0,0 +1,33 @@ +/* + * personalities.h + * + * Created on: 20 Nov 2023 + * Author: marcusbirkin + */ + +#include "personalities.h" + +#include + +uint8_t Personalities::toPersonalityIdx(Personality personality) +{ + return static_cast(personality) + 1; +} + +Personalities::Personality Personalities::fromPersonalityIdx(uint8_t nPersonality) +{ + assert(nPersonality >= 1); + return static_cast(nPersonality - 1); +} + +pixel::Type Personalities::toPixelType(Personalities::Personality personality) +{ + assert(static_cast(personality) < static_cast(pixel::Type::UNDEFINED)); + return static_cast(personality); +} + +Personalities::Personality Personalities::fromPixelType(pixel::Type type) +{ + assert(static_cast(type) < PERSONALITY_COUNT); + return static_cast(type); +} diff --git a/gd32_rdm_responder/lib/personalityupdate.cpp b/gd32_rdm_responder/lib/personalityupdate.cpp index ebe9628..2825fff 100644 --- a/gd32_rdm_responder/lib/personalityupdate.cpp +++ b/gd32_rdm_responder/lib/personalityupdate.cpp @@ -23,20 +23,27 @@ * THE SOFTWARE. */ +#include #include +#include "displayudf.h" +#include "personalities.h" +#include "pixelpatterns.h" +#include "pixeltestpattern.h" #include "rdmresponder.h" - +#include "storepixeldmx.h" #include "ws28xxdmx.h" -#include "pixeltestpattern.h" -#include "pixelpatterns.h" -#include "displayudf.h" #include "debug.h" void RDMResponder::PersonalityUpdate(uint32_t nPersonality) { DEBUG_PRINTF("nPersonality=%u", nPersonality); +#if defined(ENABLE_CONFIG_PIDS) + const auto type = Personalities::toPixelType(Personalities::fromPersonalityIdx(nPersonality)); + StorePixelDmx::Get()->SaveType(type); +#endif + DisplayUdf::Get()->ClearLine(7); DisplayUdf::Get()->Printf(7, "%s:%d G%d %s", PixelType::GetType(WS28xxDmx::Get()->GetType()), @@ -45,18 +52,29 @@ void RDMResponder::PersonalityUpdate(uint32_t nPersonality) { PixelType::GetMap(WS28xxDmx::Get()->GetMap())); DisplayUdf::Get()->Show(); - if (nPersonality == 1) { - const auto nTestPattern = PixelTestPattern::GetPattern(); + assert(nPersonality < PERSONALITY_COUNT); + switch (nPersonality) + { + default: + { + const auto nTestPattern = PixelTestPattern::GetPattern(); - if (nTestPattern == pixelpatterns::Pattern::NONE) { - } else { - DisplayUdf::Get()->ClearLine(6); - DisplayUdf::Get()->Printf(6, "%s:%u", PixelPatterns::GetName(nTestPattern), static_cast(nTestPattern)); + if (nTestPattern == pixelpatterns::Pattern::NONE) { + } else { + DisplayUdf::Get()->ClearLine(6); + DisplayUdf::Get()->Printf(6, "%s:%u", PixelPatterns::GetName(nTestPattern), static_cast(nTestPattern)); + } + break; + } +#if !defined(ENABLE_CONFIG_PIDS) + case Personalities::CONFIG_MODE: + { + DisplayUdf::Get()->ClearLine(3); + DisplayUdf::Get()->ClearLine(4); + DisplayUdf::Get()->Write(4, "Config Mode"); + DisplayUdf::Get()->ClearLine(5); + break; } - } else if (nPersonality == 2) { - DisplayUdf::Get()->ClearLine(3); - DisplayUdf::Get()->ClearLine(4); - DisplayUdf::Get()->Write(4, "Config Mode"); - DisplayUdf::Get()->ClearLine(5); +#endif } } diff --git a/lib-c++/.settings/language.settings.xml b/lib-c++/.settings/language.settings.xml index 840cf70..b1cfe60 100644 --- a/lib-c++/.settings/language.settings.xml +++ b/lib-c++/.settings/language.settings.xml @@ -1,11 +1,14 @@ - + - - + + + + + diff --git a/lib-c/.settings/language.settings.xml b/lib-c/.settings/language.settings.xml index bc342d5..944f46e 100644 --- a/lib-c/.settings/language.settings.xml +++ b/lib-c/.settings/language.settings.xml @@ -1,11 +1,14 @@ - + - + + + + - + diff --git a/lib-configstore/.cproject b/lib-configstore/.cproject index 5d7e713..fc6268a 100755 --- a/lib-configstore/.cproject +++ b/lib-configstore/.cproject @@ -42,6 +42,7 @@ + @@ -61,6 +63,11 @@ + + + + + @@ -87,6 +95,11 @@ + + + + + @@ -115,7 +128,7 @@ - + - - diff --git a/lib-gd32/.settings/language.settings.xml b/lib-gd32/.settings/language.settings.xml index 8e28480..5823789 100644 --- a/lib-gd32/.settings/language.settings.xml +++ b/lib-gd32/.settings/language.settings.xml @@ -2,7 +2,10 @@ - + + + + diff --git a/lib-rdm/.cproject b/lib-rdm/.cproject index d6f8555..c943ae7 100644 --- a/lib-rdm/.cproject +++ b/lib-rdm/.cproject @@ -115,6 +115,7 @@ + @@ -144,6 +146,7 @@ + diff --git a/lib-rdm/include/rdm_manufacturer_pid.h b/lib-rdm/include/rdm_manufacturer_pid.h index 23b0614..71c1f27 100755 --- a/lib-rdm/include/rdm_manufacturer_pid.h +++ b/lib-rdm/include/rdm_manufacturer_pid.h @@ -6,6 +6,7 @@ #define RDM_MANUFACTURER_PID_H_ #include +#include #if ! defined (PACKED) #define PACKED __attribute__((packed)) @@ -54,6 +55,13 @@ struct ManufacturerParamData { }; bool handle_manufactureer_pid_get(const uint16_t nPid, const ManufacturerParamData *pIn, ManufacturerParamData *pOut, uint16_t& nReason); +bool handle_manufactureer_pid_set( + bool isBroadcast, + const uint16_t nPid, + const rdm::ParameterDescription ¶meterDescription, + const ManufacturerParamData *pIn, + ManufacturerParamData *pOut, + uint16_t& nReason); } // namespace rdm diff --git a/lib-rdm/include/rdmhandler.h b/lib-rdm/include/rdmhandler.h index 172bf0b..7d31bb5 100644 --- a/lib-rdm/include/rdmhandler.h +++ b/lib-rdm/include/rdmhandler.h @@ -109,6 +109,9 @@ class RDMHandler { void GetHostName(uint16_t nSubDevice); void GetDomainName(uint16_t nSubDevice); // Set +#if defined (ENABLE_RDM_MANUFACTURER_PIDS) + void SetManufacturerPid(bool IsBroadcast, uint16_t nSubDevice); +#endif void SetDeviceLabel(bool IsBroadcast, uint16_t nSubDevice); void SetFactoryDefaults(bool IsBroadcast, uint16_t nSubDevice); void SetLanguage(bool IsBroadcast, uint16_t nSubDevice); diff --git a/lib-rdm/src/rdmhandler.cpp b/lib-rdm/src/rdmhandler.cpp index af4ce2d..3c8d193 100644 --- a/lib-rdm/src/rdmhandler.cpp +++ b/lib-rdm/src/rdmhandler.cpp @@ -135,7 +135,8 @@ const RDMHandler::PidDefinition RDMHandler::PID_DEFINITIONS_SUB_DEVICES[] { }; #if defined (ENABLE_RDM_MANUFACTURER_PIDS) -const RDMHandler::PidDefinition RDMHandler::PID_DEFINITION_MANUFACTURER_GENERAL { 0, &RDMHandler::GetManufacturerPid, nullptr, 0, false, true, false }; +const RDMHandler::PidDefinition RDMHandler::PID_DEFINITION_MANUFACTURER_GENERAL + {0, &RDMHandler::GetManufacturerPid, &RDMHandler::SetManufacturerPid, 0, false, true, false }; #endif RDMHandler::RDMHandler(bool bIsRdm): m_bIsRDM(bIsRdm) { @@ -568,8 +569,31 @@ void RDMHandler::GetManufacturerPid(__attribute__((unused)) uint16_t nSubDevice RespondMessageNack(nReason); } -#endif -#endif + +void RDMHandler::SetManufacturerPid(bool IsBroadcast, __attribute__((unused)) uint16_t nSubDevice) { + const auto *pRdmDataIn = reinterpret_cast(m_pRdmDataIn); + auto *pRdmDataOut = reinterpret_cast(m_pRdmDataOut); + + const auto nPid = static_cast(pRdmDataIn->param_id[0] + (pRdmDataIn->param_id[1] << 8)); + const rdm::ManufacturerParamData pIn = { pRdmDataIn->param_data_length, const_cast(pRdmDataIn->param_data) }; + rdm::ManufacturerParamData pOut = { 0, pRdmDataOut->param_data }; + uint16_t nReason = E120_NR_UNKNOWN_PID; + + for (uint32_t n = 0; n < GetParameterDescriptionCount(); ++n) + { + if ((PARAMETER_DESCRIPTIONS[n].pid == nPid) + && (rdm::handle_manufactureer_pid_set(IsBroadcast, nPid, PARAMETER_DESCRIPTIONS[n], &pIn, &pOut, nReason))) + { + pRdmDataOut->param_data_length = pOut.nPdl; + RespondMessageAck(); + return; + } + } + + RespondMessageNack(nReason); +} +#endif // ENABLE_RDM_MANUFACTURER_PIDS +#endif // !NODE_RDMNET_LLRP_ONLY void RDMHandler::GetDeviceInfo(uint16_t nSubDevice) { const auto *pRdmDeviceInfoRequested = RDMDeviceResponder::Get()->GetDeviceInfo(nSubDevice); diff --git a/lib-usb/.settings/language.settings.xml b/lib-usb/.settings/language.settings.xml index 4754df8..711c609 100755 --- a/lib-usb/.settings/language.settings.xml +++ b/lib-usb/.settings/language.settings.xml @@ -2,10 +2,13 @@ - + + + + - + diff --git a/lib-ws28xx/.settings/language.settings.xml b/lib-ws28xx/.settings/language.settings.xml index e164377..6e40eee 100644 --- a/lib-ws28xx/.settings/language.settings.xml +++ b/lib-ws28xx/.settings/language.settings.xml @@ -2,7 +2,10 @@ - + + + + diff --git a/lib-ws28xx/include/pixelconfiguration.h b/lib-ws28xx/include/pixelconfiguration.h index 25ecdda..211fa07 100644 --- a/lib-ws28xx/include/pixelconfiguration.h +++ b/lib-ws28xx/include/pixelconfiguration.h @@ -41,11 +41,11 @@ class PixelConfiguration { return m_type; } - void SetCount(uint32_t nCount) { + void SetCount(uint16_t nCount) { m_nCount = nCount == 0 ? pixel::defaults::COUNT : nCount; } - uint32_t GetCount() const { + uint16_t GetCount() const { return m_nCount; } @@ -123,7 +123,7 @@ class PixelConfiguration { private: pixel::Type m_type { pixel::defaults::TYPE }; - uint32_t m_nCount { pixel::defaults::COUNT }; + uint16_t m_nCount { pixel::defaults::COUNT }; pixel::Map m_map { pixel::Map::UNDEFINED }; uint32_t m_nClockSpeedHz { 0 }; uint8_t m_nLowCode { 0 }; diff --git a/lib-ws28xxdmx/.cproject b/lib-ws28xxdmx/.cproject index 5926b48..d1c1919 100644 --- a/lib-ws28xxdmx/.cproject +++ b/lib-ws28xxdmx/.cproject @@ -14,7 +14,7 @@ - + @@ -152,6 +155,7 @@ + diff --git a/lib-ws28xxdmx/Rules.mk b/lib-ws28xxdmx/Rules.mk index 0649b27..ab875d0 100644 --- a/lib-ws28xxdmx/Rules.mk +++ b/lib-ws28xxdmx/Rules.mk @@ -1,6 +1,8 @@ EXTRA_INCLUDES+=../lib-ws28xx/include EXTRA_INCLUDES+=../lib-lightset/include -EXTRA_INCLUDES+=../lib-properties/include +EXTRA_INCLUDES+=../lib-properties/include +EXTRA_INCLUDES+=../lib-configstore/include +EXTRA_INCLUDES+=../lib-flashcode/include EXTRA_SRCDIR+=src/params diff --git a/lib-ws28xxdmx/include/pixeldmxconfiguration.h b/lib-ws28xxdmx/include/pixeldmxconfiguration.h index 5a24a34..aeffb2e 100644 --- a/lib-ws28xxdmx/include/pixeldmxconfiguration.h +++ b/lib-ws28xxdmx/include/pixeldmxconfiguration.h @@ -51,7 +51,7 @@ class PixelDmxConfiguration: public PixelConfiguration { m_nGroupingCount = nGroupingCount; } - uint32_t GetGroupingCount() const { + uint16_t GetGroupingCount() const { return m_nGroupingCount; } @@ -77,7 +77,7 @@ class PixelDmxConfiguration: public PixelConfiguration { private: uint32_t m_nOutputPorts { 1 }; - uint32_t m_nGroupingCount { 1 }; + uint16_t m_nGroupingCount { 1 }; uint32_t m_nGroups { pixel::defaults::COUNT }; uint32_t m_nUniverses; uint16_t m_nDmxStartAddress { 1 }; diff --git a/lib-ws28xxdmx/include/pixeldmxstore.h b/lib-ws28xxdmx/include/pixeldmxstore.h index 58476b9..75231d7 100644 --- a/lib-ws28xxdmx/include/pixeldmxstore.h +++ b/lib-ws28xxdmx/include/pixeldmxstore.h @@ -28,12 +28,17 @@ #include +namespace pixel { + enum class Type; +} + class PixelDmxStore { public: virtual ~PixelDmxStore() { } virtual void SaveType(uint8_t nType)=0; + virtual void SaveType(pixel::Type type)=0; virtual void SaveCount(uint16_t nCount)=0; virtual void SaveGroupingCount(uint16_t nGroupingCount)=0; virtual void SaveMap(uint8_t nMap)=0; diff --git a/lib-ws28xxdmx/include/ws28xxdmx.h b/lib-ws28xxdmx/include/ws28xxdmx.h index b131d39..6d21105 100644 --- a/lib-ws28xxdmx/include/ws28xxdmx.h +++ b/lib-ws28xxdmx/include/ws28xxdmx.h @@ -36,10 +36,11 @@ #include "pixelpatterns.h" #include "pixeldmxstore.h" #include "pixeldmxhandler.h" +#include "storepixeldmx.h" class WS28xxDmx final: public LightSet { public: - WS28xxDmx(PixelDmxConfiguration& pixelDmxConfiguration); + WS28xxDmx(PixelDmxConfiguration& pixelDmxConfiguration, StorePixelDmx* storePixelDmx = nullptr); ~WS28xxDmx() override; void Start(const uint32_t nPortIndex) override; @@ -84,18 +85,48 @@ class WS28xxDmx final: public LightSet { return m_pixelDmxConfiguration.GetMap(); } - uint32_t GetCount() const { + bool SetMap(pixel::Map tMap) { + m_pixelDmxConfiguration.SetMap(tMap); + if (m_pStorePixelDmx) + { + m_pStorePixelDmx->SaveMap(static_cast(tMap)); + return true; + } + return false; + } + + uint16_t GetCount() const { return m_pixelDmxConfiguration.GetCount(); } + bool SetCount(uint16_t nCount) { + m_pixelDmxConfiguration.SetCount(nCount); + if (m_pStorePixelDmx) + { + m_pStorePixelDmx->SaveCount(nCount); + return true; + } + return false; + } + uint32_t GetGroups() const { return m_pixelDmxConfiguration.GetGroups(); } - uint32_t GetGroupingCount() const { + uint16_t GetGroupingCount() const { return m_pixelDmxConfiguration.GetGroupingCount(); } + bool SetGroupingCount(uint16_t nGroupingCount) { + m_pixelDmxConfiguration.SetGroupingCount(nGroupingCount); + if (m_pStorePixelDmx) + { + m_pStorePixelDmx->SaveGroupingCount(nGroupingCount); + return true; + } + return false; + } + uint32_t GetUniverses() const { return m_pixelDmxConfiguration.GetUniverses(); } @@ -119,6 +150,7 @@ class WS28xxDmx final: public LightSet { private: PixelDmxConfiguration m_pixelDmxConfiguration; + StorePixelDmx* m_pStorePixelDmx; pixeldmxconfiguration::PortInfo m_PortInfo; uint32_t m_nChannelsPerPixel; diff --git a/lib-ws28xxdmx/src/dmx/ws28xxdmx.cpp b/lib-ws28xxdmx/src/dmx/ws28xxdmx.cpp index 5c39c61..da1a860 100755 --- a/lib-ws28xxdmx/src/dmx/ws28xxdmx.cpp +++ b/lib-ws28xxdmx/src/dmx/ws28xxdmx.cpp @@ -43,7 +43,9 @@ WS28xxDmx *WS28xxDmx::s_pThis; -WS28xxDmx::WS28xxDmx(PixelDmxConfiguration& pixelDmxConfiguration): m_pixelDmxConfiguration(pixelDmxConfiguration) { +WS28xxDmx::WS28xxDmx(PixelDmxConfiguration& pixelDmxConfiguration, StorePixelDmx* storePixelDmx) + : m_pixelDmxConfiguration(pixelDmxConfiguration), m_pStorePixelDmx(storePixelDmx) +{ DEBUG_ENTRY assert(s_pThis == nullptr); diff --git a/lib-ws28xxdmx/src/rdm/rdm_manufacturer_pid.cpp b/lib-ws28xxdmx/src/rdm/rdm_manufacturer_pid.cpp index a80e608..5094ed4 100755 --- a/lib-ws28xxdmx/src/rdm/rdm_manufacturer_pid.cpp +++ b/lib-ws28xxdmx/src/rdm/rdm_manufacturer_pid.cpp @@ -84,8 +84,12 @@ const rdm::ParameterDescription RDMHandler::PARAMETER_DESCRIPTIONS[] = { }, { rdm::E120_MANUFACTURER_PIXEL_COUNT::code, 2, - E120_DS_UNSIGNED_DWORD, + E120_DS_UNSIGNED_WORD, +#if defined(ENABLE_CONFIG_PIDS) + E120_CC_GET_SET, +#else E120_CC_GET, +#endif 0, E120_UNITS_NONE, E120_PREFIX_NONE, @@ -97,8 +101,12 @@ const rdm::ParameterDescription RDMHandler::PARAMETER_DESCRIPTIONS[] = { }, { rdm::E120_MANUFACTURER_PIXEL_GROUPING_COUNT::code, 2, - E120_DS_UNSIGNED_DWORD, + E120_DS_UNSIGNED_WORD, +#if defined(ENABLE_CONFIG_PIDS) + E120_CC_GET_SET, +#else E120_CC_GET, +#endif 0, E120_UNITS_NONE, E120_PREFIX_NONE, @@ -111,7 +119,11 @@ const rdm::ParameterDescription RDMHandler::PARAMETER_DESCRIPTIONS[] = { { rdm::E120_MANUFACTURER_PIXEL_MAP::code, rdm::DEVICE_DESCRIPTION_MAX_LENGTH, E120_DS_ASCII, +#if defined(ENABLE_CONFIG_PIDS) + E120_CC_GET_SET, +#else E120_CC_GET, +#endif 0, E120_UNITS_NONE, E120_PREFIX_NONE, @@ -140,20 +152,16 @@ bool handle_manufactureer_pid_get(const uint16_t nPid, __attribute__((unused)) c } case rdm::E120_MANUFACTURER_PIXEL_COUNT::code: { const auto nCount = WS28xxDmx::Get()->GetCount(); - pOut->nPdl = 4; - pOut->pParamData[0] = static_cast(nCount >> 24); - pOut->pParamData[1] = static_cast(nCount >> 16); - pOut->pParamData[2] = static_cast(nCount >> 8); - pOut->pParamData[3] = static_cast(nCount); + pOut->nPdl = 2; + pOut->pParamData[0] = static_cast(nCount >> 8); + pOut->pParamData[1] = static_cast(nCount); return true; } case rdm::E120_MANUFACTURER_PIXEL_GROUPING_COUNT::code: { const auto nGroupingCount = WS28xxDmx::Get()->GetGroupingCount(); - pOut->nPdl = 4; - pOut->pParamData[0] = static_cast(nGroupingCount >> 24); - pOut->pParamData[1] = static_cast(nGroupingCount >> 16); - pOut->pParamData[2] = static_cast(nGroupingCount >> 8); - pOut->pParamData[3] = static_cast(nGroupingCount); + pOut->nPdl = 2; + pOut->pParamData[0] = static_cast(nGroupingCount >> 8); + pOut->pParamData[1] = static_cast(nGroupingCount); return true; } case rdm::E120_MANUFACTURER_PIXEL_MAP::code: { @@ -169,4 +177,86 @@ bool handle_manufactureer_pid_get(const uint16_t nPid, __attribute__((unused)) c nReason = E120_NR_UNKNOWN_PID; return false; } + +#if defined(ENABLE_CONFIG_PIDS) +bool handle_manufactureer_pid_set( + bool isBroadcast, + const uint16_t nPid, + const rdm::ParameterDescription ¶meterDescription, + const ManufacturerParamData *pIn, + [[maybe_unused]] ManufacturerParamData *pOut, + uint16_t& nReason) +{ + if (isBroadcast) + { + return false; + } + + switch (nPid) + { + case rdm::E120_MANUFACTURER_PIXEL_COUNT::code: { + if (pIn->nPdl == 2) + { + uint16_t nCount = pIn->pParamData[1]; + nCount |= pIn->pParamData[0] << 8; + if ((nCount < parameterDescription.min_value) + || (nCount > parameterDescription.max_value)) + { + nReason = E120_NR_DATA_OUT_OF_RANGE; + return false; + } + + nReason = E120_NR_HARDWARE_FAULT; // Only used if the below fails + return WS28xxDmx::Get()->SetCount(nCount); + } + + nReason = E120_NR_FORMAT_ERROR; + return false; + } + + case rdm::E120_MANUFACTURER_PIXEL_GROUPING_COUNT::code: { + if (pIn->nPdl == 2) + { + uint16_t nGroupingCount = pIn->pParamData[1]; + nGroupingCount |= pIn->pParamData[0] << 8; + if ((nGroupingCount < parameterDescription.min_value) + || (nGroupingCount > parameterDescription.max_value)) + { + nReason = E120_NR_DATA_OUT_OF_RANGE; + return false; + } + + nReason = E120_NR_HARDWARE_FAULT; // Only used if the below fails + return WS28xxDmx::Get()->SetGroupingCount(nGroupingCount); + } + + nReason = E120_NR_FORMAT_ERROR; + return false; + } + + case rdm::E120_MANUFACTURER_PIXEL_MAP::code: { + if (pIn->nPdl == 3) + { + const auto map = ::PixelType::GetMap(reinterpret_cast(pIn->pParamData)); + if (map != pixel::Map::UNDEFINED) + { + nReason = E120_NR_HARDWARE_FAULT; // Only used if the below fails + return WS28xxDmx::Get()->SetMap(map); + } + + nReason = E120_NR_DATA_OUT_OF_RANGE; + return false; + } + + nReason = E120_NR_FORMAT_ERROR; + return false; + } + + default: + nReason = E120_NR_UNKNOWN_PID; + return false; + } +} +#endif + } // namespace rdm