Skip to content

Commit

Permalink
Merge e5b3b0c into 5fa67e5
Browse files Browse the repository at this point in the history
  • Loading branch information
CreaValix committed Jul 27, 2023
2 parents 5fa67e5 + e5b3b0c commit 5415417
Show file tree
Hide file tree
Showing 13 changed files with 383 additions and 1 deletion.
8 changes: 8 additions & 0 deletions plugins/usbdmx/AsyncPluginImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "plugins/usbdmx/ScanlimeFadecandy.h"
#include "plugins/usbdmx/ScanlimeFadecandyFactory.h"
#include "plugins/usbdmx/ShowJockeyDMXU1Factory.h"
#include "plugins/usbdmx/SiudiFactory.h"
#include "plugins/usbdmx/SunliteFactory.h"
#include "plugins/usbdmx/VellemanK8062.h"
#include "plugins/usbdmx/VellemanK8062Factory.h"
Expand Down Expand Up @@ -132,6 +133,7 @@ bool AsyncPluginImpl::Start() {
m_widget_factories.push_back(
new ScanlimeFadecandyFactory(m_usb_adaptor));
m_widget_factories.push_back(new ShowJockeyDMXU1Factory(m_usb_adaptor));
m_widget_factories.push_back(new SiudiFactory(m_usb_adaptor));
m_widget_factories.push_back(new SunliteFactory(m_usb_adaptor));
m_widget_factories.push_back(new VellemanK8062Factory(m_usb_adaptor));

Expand Down Expand Up @@ -233,6 +235,12 @@ bool AsyncPluginImpl::NewWidget(ShowJockeyDMXU1 *widget) {
"showjockey-dmx-u1-" + widget->SerialNumber()));
}

bool AsyncPluginImpl::NewWidget(Siudi *widget) {
return StartAndRegisterDevice(
widget,
new GenericDevice(m_plugin, widget, "Nicolaudie SIUDI", "usbsiudi"));
}

bool AsyncPluginImpl::NewWidget(Sunlite *widget) {
return StartAndRegisterDevice(
widget,
Expand Down
1 change: 1 addition & 0 deletions plugins/usbdmx/AsyncPluginImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class AsyncPluginImpl: public PluginImplInterface, public WidgetObserver {
bool NewWidget(ola::usb::JaRuleWidget *widget);
bool NewWidget(class ScanlimeFadecandy *widget);
bool NewWidget(class ShowJockeyDMXU1 *widget);
bool NewWidget(class Siudi *widget);
bool NewWidget(class Sunlite *widget);
bool NewWidget(class VellemanK8062 *widget);

Expand Down
4 changes: 4 additions & 0 deletions plugins/usbdmx/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ plugins_usbdmx_libolausbdmxwidget_la_SOURCES = \
plugins/usbdmx/ShowJockeyDMXU1.h \
plugins/usbdmx/ShowJockeyDMXU1Factory.cpp \
plugins/usbdmx/ShowJockeyDMXU1Factory.h \
plugins/usbdmx/Siudi.cpp \
plugins/usbdmx/Siudi.h \
plugins/usbdmx/SiudiFactory.cpp \
plugins/usbdmx/SiudiFactory.h \
plugins/usbdmx/Sunlite.cpp \
plugins/usbdmx/Sunlite.h \
plugins/usbdmx/SunliteFactory.cpp \
Expand Down
1 change: 1 addition & 0 deletions plugins/usbdmx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This plugin supports various USB DMX devices including:
* FX5 DMX
* ShowJockey SJ-DMX-U1
* Sunlite USBDMX2
* Nicoleaudie Sunlite intelligent USB DMX interface (SIUDI) (also ADJ MyDMX)
* Velleman K8062.


Expand Down
155 changes: 155 additions & 0 deletions plugins/usbdmx/Siudi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Siudi.cpp
* The synchronous SIUDI widgets.
* Copyright (C) 2023 Alexander Simon
*/

#include "plugins/usbdmx/Siudi.h"

#include <string.h>
#include <unistd.h>

#include "libs/usb/LibUsbAdaptor.h"
#include "ola/Constants.h"
#include "ola/Logging.h"
#include "plugins/usbdmx/AsyncUsbSender.h"
#include "plugins/usbdmx/ThreadedUsbSender.h"

namespace ola {
namespace plugin {
namespace usbdmx {

using ola::usb::LibUsbAdaptor;

namespace {

static const uint8_t ENDPOINT = 2;
static const unsigned int TIMEOUT = 50; // 50ms is ok
enum {SIUDI_PACKET_SIZE = 512};

} // namespace

// SiudiThreadedSender
// -----------------------------------------------------------------------------

/*
* Sends messages to a SIUDI device in a separate thread.
*/
class SiudiThreadedSender: public ThreadedUsbSender {
public:
SiudiThreadedSender(LibUsbAdaptor *adaptor,
libusb_device *usb_device,
libusb_device_handle *handle);

bool Start();

private:
LibUsbAdaptor* const m_adaptor;
uint8_t m_packet[SIUDI_PACKET_SIZE];
libusb_device_handle* const m_usb_handle;

bool TransmitBuffer(libusb_device_handle *handle,
const DmxBuffer &buffer);
};

SiudiThreadedSender::SiudiThreadedSender(
LibUsbAdaptor *adaptor,
libusb_device *usb_device,
libusb_device_handle *usb_handle)
: ThreadedUsbSender(usb_device, usb_handle),
m_adaptor(adaptor), m_usb_handle(usb_handle) {
memset(m_packet, 0x00, SIUDI_PACKET_SIZE);
}

bool SiudiThreadedSender::Start() {
if (!ThreadedUsbSender::Start()) {
return false;
}

// Read device info. This call takes about 270 ms.
// Discard the buffer as the format is currently unknown.
uint8_t buf[64];
int ret = libusb_control_transfer(m_usb_handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
0x3f, 0x00c4, 1, buf, 64, 500);
if (ret != 64) {
OLA_WARN << "Failed to read SIUDI information: "
<< (ret < 0 ? LibUsbAdaptor::ErrorCodeToString(ret) : "Short read");
return false;
}

// Unstall the endpoint. The original software seems to call this regularly.
ret = libusb_clear_halt(m_usb_handle, ENDPOINT);
if (ret != 0) {
OLA_WARN << "Failed to reset SIUDI endpoint: "
<< (ret < 0 ? LibUsbAdaptor::ErrorCodeToString(ret) : "Unknown");
return false;
}
usleep(10000);

return true;
}

bool SiudiThreadedSender::TransmitBuffer(libusb_device_handle *handle,
const DmxBuffer &buffer) {
for (unsigned int i = 0; i < buffer.Size(); i++) {
m_packet[i] = buffer.Get(i);
}
int transferred;
int r = m_adaptor->BulkTransfer(
handle, ENDPOINT, (unsigned char*) m_packet,
SIUDI_PACKET_SIZE, &transferred, TIMEOUT);
if (transferred != SIUDI_PACKET_SIZE) {
// not sure if this is fatal or not
OLA_WARN << "SIUDI driver failed to transfer all data";
}
usleep(20000);
return r == 0;
}

// SynchronousSiudi
// -----------------------------------------------------------------------------

SynchronousSiudi::SynchronousSiudi(LibUsbAdaptor *adaptor,
libusb_device *usb_device)
: Siudi(adaptor, usb_device) {
}

bool SynchronousSiudi::Init() {
libusb_device_handle *usb_handle;

bool ok = m_adaptor->OpenDeviceAndClaimInterface(
m_usb_device, 0, &usb_handle);
if (!ok) {
return false;
}

std::auto_ptr<SiudiThreadedSender> sender(
new SiudiThreadedSender(m_adaptor, m_usb_device, usb_handle));
if (!sender->Start()) {
return false;
}
m_sender.reset(sender.release());
return true;
}

bool SynchronousSiudi::SendDMX(const DmxBuffer &buffer) {
return m_sender.get() ? m_sender->SendDMX(buffer) : false;
}
} // namespace usbdmx
} // namespace plugin
} // namespace ola
76 changes: 76 additions & 0 deletions plugins/usbdmx/Siudi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Siudi.h
* The synchronous SIUDI widgets.
* Copyright (C) 2023 Alexander Simon
*/

#ifndef PLUGINS_USBDMX_SIUDI_H_
#define PLUGINS_USBDMX_SIUDI_H_

#include <libusb.h>
#include <memory>
#include "ola/DmxBuffer.h"
#include "ola/base/Macro.h"
#include "ola/thread/Mutex.h"
#include "plugins/usbdmx/Widget.h"

namespace ola {
namespace plugin {
namespace usbdmx {

class SiudiThreadedSender;

/**
* @brief The interface for the Siudi Widgets
*/
class Siudi : public SimpleWidget {
public:
explicit Siudi(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device)
: SimpleWidget(adaptor, usb_device) {
}
};


/**
* @brief An SIUDI widget that uses synchronous libusb operations.
*
* Internally this spawns a new thread to avoid blocking SendDMX() calls.
*/
class SynchronousSiudi: public Siudi {
public:
/**
* @brief Create a new SynchronousSiudi.
* @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget.
*/
SynchronousSiudi(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device);

bool Init();

bool SendDMX(const DmxBuffer &buffer);

private:
std::auto_ptr<class ThreadedUsbSender> m_sender;

DISALLOW_COPY_AND_ASSIGN(SynchronousSiudi);
};
} // namespace usbdmx
} // namespace plugin
} // namespace ola
#endif // PLUGINS_USBDMX_SIUDI_H_
51 changes: 51 additions & 0 deletions plugins/usbdmx/SiudiFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* SiudiFactory.cpp
* The WidgetFactory for SIUDI widgets.
* Copyright (C) 2023 Alexander Simon
*/

#include "plugins/usbdmx/SiudiFactory.h"

#include "ola/Logging.h"
#include "ola/base/Flags.h"

DECLARE_bool(use_async_libusb);

namespace ola {
namespace plugin {
namespace usbdmx {

const uint16_t SiudiFactory::VENDOR_ID = 0x6244;
const uint16_t SiudiFactory::COLD_PRODUCT_ID = 0x0300;
const uint16_t SiudiFactory::HOT_PRODUCT_ID = 0x0301;

bool SiudiFactory::DeviceAdded(
WidgetObserver *observer,
libusb_device *usb_device,
const struct libusb_device_descriptor &descriptor) {
if (descriptor.idVendor == VENDOR_ID &&
descriptor.idProduct == HOT_PRODUCT_ID) {
OLA_INFO << "Found a new Nicoleaudie SIUDI-6 device";
Siudi *widget = NULL;
widget = new SynchronousSiudi(m_adaptor, usb_device);
return AddWidget(observer, widget);
}
return false;
}
} // namespace usbdmx
} // namespace plugin
} // namespace ola
Loading

0 comments on commit 5415417

Please sign in to comment.