From 4505ce0dbeb25f373f4504b2564797d9278ba5ac Mon Sep 17 00:00:00 2001 From: rbalykov Date: Sun, 2 Aug 2020 15:35:55 +0300 Subject: [PATCH 1/3] Added '-padding' option to uartdmx plugin. Sets minimal slots count in UART frame. Default is 0, will behave as before. --- plugins/uartdmx/UartDmxDevice.cpp | 13 ++++++++++++- plugins/uartdmx/UartDmxDevice.h | 4 ++++ plugins/uartdmx/UartWidget.cpp | 8 +++++++- plugins/uartdmx/UartWidget.h | 4 ++-- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/plugins/uartdmx/UartDmxDevice.cpp b/plugins/uartdmx/UartDmxDevice.cpp index 83a15348b2..481e26d908 100644 --- a/plugins/uartdmx/UartDmxDevice.cpp +++ b/plugins/uartdmx/UartDmxDevice.cpp @@ -34,8 +34,10 @@ using std::string; const char UartDmxDevice::K_MALF[] = "-malf"; const char UartDmxDevice::K_BREAK[] = "-break"; +const char UartDmxDevice::K_PADDING[] = "-padding"; const unsigned int UartDmxDevice::DEFAULT_BREAK = 100; const unsigned int UartDmxDevice::DEFAULT_MALF = 100; +const unsigned int UartDmxDevice::DEFAULT_PADDING = 0; // at least 0 slots in frame UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, @@ -57,7 +59,10 @@ UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, if (!StringToInt(m_preferences->GetValue(DeviceMalfKey()), &m_malft)) { m_malft = DEFAULT_MALF; } - m_widget.reset(new UartWidget(path)); + if (!StringToInt(m_preferences->GetValue(DevicePaddingKey()), &m_paddingt)) { + m_paddingt = DEFAULT_PADDING; + } + m_widget.reset(new UartWidget(path, m_paddingt)); } UartDmxDevice::~UartDmxDevice() { @@ -77,6 +82,9 @@ string UartDmxDevice::DeviceMalfKey() const { string UartDmxDevice::DeviceBreakKey() const { return m_path + K_BREAK; } +string UartDmxDevice::DevicePaddingKey() const { + return m_path + K_PADDING; +} /** * Set the default preferences for this one Device @@ -94,6 +102,9 @@ void UartDmxDevice::SetDefaults() { save |= m_preferences->SetDefaultValue(DeviceMalfKey(), UIntValidator(8, 1000000), DEFAULT_MALF); + save |= m_preferences->SetDefaultValue(DevicePaddingKey(), + UIntValidator(0, 512), // 0 to 512 slots in frame + DEFAULT_PADDING); if (save) { m_preferences->Save(); } diff --git a/plugins/uartdmx/UartDmxDevice.h b/plugins/uartdmx/UartDmxDevice.h index b4efbb388e..492e49783b 100644 --- a/plugins/uartdmx/UartDmxDevice.h +++ b/plugins/uartdmx/UartDmxDevice.h @@ -52,6 +52,7 @@ class UartDmxDevice : public Device { // Per device options std::string DeviceBreakKey() const; std::string DeviceMalfKey() const; + std::string DevicePaddingKey() const; void SetDefaults(); std::auto_ptr m_widget; @@ -60,11 +61,14 @@ class UartDmxDevice : public Device { const std::string m_path; unsigned int m_breakt; unsigned int m_malft; + unsigned int m_paddingt; static const unsigned int DEFAULT_MALF; static const char K_MALF[]; static const unsigned int DEFAULT_BREAK; static const char K_BREAK[]; + static const unsigned int DEFAULT_PADDING; + static const char K_PADDING[]; DISALLOW_COPY_AND_ASSIGN(UartDmxDevice); }; diff --git a/plugins/uartdmx/UartWidget.cpp b/plugins/uartdmx/UartWidget.cpp index d0fc3a709c..2d89b503cf 100644 --- a/plugins/uartdmx/UartWidget.cpp +++ b/plugins/uartdmx/UartWidget.cpp @@ -46,6 +46,7 @@ #include "ola/io/IOUtils.h" #include "ola/Logging.h" #include "plugins/uartdmx/UartWidget.h" +#include "plugins/uartdmx/UartDmxDevice.h" namespace ola { namespace plugin { @@ -54,8 +55,9 @@ namespace uartdmx { using std::string; using std::vector; -UartWidget::UartWidget(const string& path) +UartWidget::UartWidget(const std::string &path, unsigned int padding) : m_path(path), + m_padding (padding), m_fd(NOT_OPEN) { } @@ -122,6 +124,10 @@ bool UartWidget::Write(const ola::DmxBuffer& data) { buffer[0] = DMX512_START_CODE; data.Get(buffer + 1, &length); + if (length < m_padding) { + memset ((buffer + 1 + length), 0x00, (m_padding - length) ); + length = m_padding; + } if (write(m_fd, buffer, length + 1) <= 0) { // TODO(richardash1981): handle errors better as per the test code, diff --git a/plugins/uartdmx/UartWidget.h b/plugins/uartdmx/UartWidget.h index 81faf15fe7..7215a50070 100644 --- a/plugins/uartdmx/UartWidget.h +++ b/plugins/uartdmx/UartWidget.h @@ -49,8 +49,7 @@ class UartWidget { * Construct a new UartWidget instance for one widget. * @param path The device file path of the serial port */ - explicit UartWidget(const std::string &path); - + explicit UartWidget(const std::string &path, unsigned int padding); /** Destructor */ virtual ~UartWidget(); @@ -81,6 +80,7 @@ class UartWidget { private: const std::string m_path; + unsigned int m_padding; /** * variable to hold the Unix file descriptor used to open and manipulate From cfb0cb53c2b349a1a78b2dc036c636333cd1cdb4 Mon Sep 17 00:00:00 2001 From: rbalykov Date: Sun, 2 Aug 2020 15:35:55 +0300 Subject: [PATCH 2/3] Added '-padding' option to uartdmx plugin. Sets minimal slots count in UART frame. Default is 0, will behave as before. --- plugins/uartdmx/README.md | 34 +++++++++++++++++++++++++++++++ plugins/uartdmx/UartDmxDevice.cpp | 13 +++++++++++- plugins/uartdmx/UartDmxDevice.h | 4 ++++ plugins/uartdmx/UartWidget.cpp | 8 +++++++- plugins/uartdmx/UartWidget.h | 4 ++-- 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 plugins/uartdmx/README.md diff --git a/plugins/uartdmx/README.md b/plugins/uartdmx/README.md new file mode 100644 index 0000000000..8957e95701 --- /dev/null +++ b/plugins/uartdmx/README.md @@ -0,0 +1,34 @@ +Native UART DMX Plugin +====================== + +This plugin drives a supported POSIX UART (plus extensions) to produce a +direct DMX output stream. The host needs to create the DMX stream itself as +there is no external microcontroller. + +This is tested with the on-board UART of the Raspberry Pi. See here for a +possible schematic: +http://eastertrail.blogspot.co.uk/2014/04/command-and-control-ii.html + + +## Config file: `ola-uartdmx.conf` + +`enabled = true` +Enable this plugin (DISABLED by default). + +`device = /dev/ttyAMA0` +The device to use for DMX output (optional). Multiple devices are supported +if the hardware exists. On later software it may also be /dev/serial0. +Using USB-serial adapters is not supported (try the +*ftdidmx* plugin instead). + + +### Per Device Settings (using above device name) + +`-break = 100` +The DMX break time in microseconds for this device (optional). + +`-malf = 100` +The Mark After Last Frame time in microseconds for this device (optional). + +`-padding = 0` Minimal slots count in DMX frame (optional). +Default is 0, which allows empty frame. Using minimal timing, frame period reaches 140 microseconds, while standard requires minimum 1204us. Using BREAK=88us and MAB=8us, frame has to include 25 slots, that gives frame period 1240us. diff --git a/plugins/uartdmx/UartDmxDevice.cpp b/plugins/uartdmx/UartDmxDevice.cpp index 83a15348b2..481e26d908 100644 --- a/plugins/uartdmx/UartDmxDevice.cpp +++ b/plugins/uartdmx/UartDmxDevice.cpp @@ -34,8 +34,10 @@ using std::string; const char UartDmxDevice::K_MALF[] = "-malf"; const char UartDmxDevice::K_BREAK[] = "-break"; +const char UartDmxDevice::K_PADDING[] = "-padding"; const unsigned int UartDmxDevice::DEFAULT_BREAK = 100; const unsigned int UartDmxDevice::DEFAULT_MALF = 100; +const unsigned int UartDmxDevice::DEFAULT_PADDING = 0; // at least 0 slots in frame UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, @@ -57,7 +59,10 @@ UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, if (!StringToInt(m_preferences->GetValue(DeviceMalfKey()), &m_malft)) { m_malft = DEFAULT_MALF; } - m_widget.reset(new UartWidget(path)); + if (!StringToInt(m_preferences->GetValue(DevicePaddingKey()), &m_paddingt)) { + m_paddingt = DEFAULT_PADDING; + } + m_widget.reset(new UartWidget(path, m_paddingt)); } UartDmxDevice::~UartDmxDevice() { @@ -77,6 +82,9 @@ string UartDmxDevice::DeviceMalfKey() const { string UartDmxDevice::DeviceBreakKey() const { return m_path + K_BREAK; } +string UartDmxDevice::DevicePaddingKey() const { + return m_path + K_PADDING; +} /** * Set the default preferences for this one Device @@ -94,6 +102,9 @@ void UartDmxDevice::SetDefaults() { save |= m_preferences->SetDefaultValue(DeviceMalfKey(), UIntValidator(8, 1000000), DEFAULT_MALF); + save |= m_preferences->SetDefaultValue(DevicePaddingKey(), + UIntValidator(0, 512), // 0 to 512 slots in frame + DEFAULT_PADDING); if (save) { m_preferences->Save(); } diff --git a/plugins/uartdmx/UartDmxDevice.h b/plugins/uartdmx/UartDmxDevice.h index b4efbb388e..492e49783b 100644 --- a/plugins/uartdmx/UartDmxDevice.h +++ b/plugins/uartdmx/UartDmxDevice.h @@ -52,6 +52,7 @@ class UartDmxDevice : public Device { // Per device options std::string DeviceBreakKey() const; std::string DeviceMalfKey() const; + std::string DevicePaddingKey() const; void SetDefaults(); std::auto_ptr m_widget; @@ -60,11 +61,14 @@ class UartDmxDevice : public Device { const std::string m_path; unsigned int m_breakt; unsigned int m_malft; + unsigned int m_paddingt; static const unsigned int DEFAULT_MALF; static const char K_MALF[]; static const unsigned int DEFAULT_BREAK; static const char K_BREAK[]; + static const unsigned int DEFAULT_PADDING; + static const char K_PADDING[]; DISALLOW_COPY_AND_ASSIGN(UartDmxDevice); }; diff --git a/plugins/uartdmx/UartWidget.cpp b/plugins/uartdmx/UartWidget.cpp index d0fc3a709c..2d89b503cf 100644 --- a/plugins/uartdmx/UartWidget.cpp +++ b/plugins/uartdmx/UartWidget.cpp @@ -46,6 +46,7 @@ #include "ola/io/IOUtils.h" #include "ola/Logging.h" #include "plugins/uartdmx/UartWidget.h" +#include "plugins/uartdmx/UartDmxDevice.h" namespace ola { namespace plugin { @@ -54,8 +55,9 @@ namespace uartdmx { using std::string; using std::vector; -UartWidget::UartWidget(const string& path) +UartWidget::UartWidget(const std::string &path, unsigned int padding) : m_path(path), + m_padding (padding), m_fd(NOT_OPEN) { } @@ -122,6 +124,10 @@ bool UartWidget::Write(const ola::DmxBuffer& data) { buffer[0] = DMX512_START_CODE; data.Get(buffer + 1, &length); + if (length < m_padding) { + memset ((buffer + 1 + length), 0x00, (m_padding - length) ); + length = m_padding; + } if (write(m_fd, buffer, length + 1) <= 0) { // TODO(richardash1981): handle errors better as per the test code, diff --git a/plugins/uartdmx/UartWidget.h b/plugins/uartdmx/UartWidget.h index 81faf15fe7..7215a50070 100644 --- a/plugins/uartdmx/UartWidget.h +++ b/plugins/uartdmx/UartWidget.h @@ -49,8 +49,7 @@ class UartWidget { * Construct a new UartWidget instance for one widget. * @param path The device file path of the serial port */ - explicit UartWidget(const std::string &path); - + explicit UartWidget(const std::string &path, unsigned int padding); /** Destructor */ virtual ~UartWidget(); @@ -81,6 +80,7 @@ class UartWidget { private: const std::string m_path; + unsigned int m_padding; /** * variable to hold the Unix file descriptor used to open and manipulate From 7892723801bc64c62dba0079ffe25d2f7a09c019 Mon Sep 17 00:00:00 2001 From: Balykov Ruslan Date: Tue, 4 Aug 2020 08:14:19 +0300 Subject: [PATCH 3/3] Fix indentation --- plugins/uartdmx/UartWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/uartdmx/UartWidget.cpp b/plugins/uartdmx/UartWidget.cpp index 8a46dd34f7..bedf57f519 100644 --- a/plugins/uartdmx/UartWidget.cpp +++ b/plugins/uartdmx/UartWidget.cpp @@ -125,7 +125,7 @@ bool UartWidget::Write(const ola::DmxBuffer& data) { data.Get(buffer + 1, &length); if (length < m_padding) { - memset((buffer + 1 + length), 0x00, (m_padding - length) ); + memset((buffer + 1 + length), 0x00, (m_padding - length) ); length = m_padding; }