Skip to content
Permalink
Browse files

Merge branch 'master' into fix-get-dimmer-max

  • Loading branch information...
peternewman committed Jun 29, 2019
2 parents 81d7b21 + c6c3842 commit de24dd605aae7dddb46afaf69cab221d8fe0fc5c
@@ -126,7 +126,7 @@ bool AsyncPluginImpl::Start() {
m_preferences));
m_widget_factories.push_back(new DMXCreator512BasicFactory(m_usb_adaptor));
m_widget_factories.push_back(
new EuroliteProFactory(m_usb_adaptor));
new EuroliteProFactory(m_usb_adaptor, m_preferences));
m_widget_factories.push_back(
new JaRuleFactory(m_plugin_adaptor, m_usb_adaptor));
m_widget_factories.push_back(
@@ -46,6 +46,8 @@ static const uint8_t DMX_LABEL = 6;
static const uint8_t START_OF_MESSAGE = 0x7e;
static const uint8_t END_OF_MESSAGE = 0xe7;
static const unsigned char ENDPOINT = 0x02;
static const uint8_t MK2_SET_BAUD_RATE = 0x03;
static const unsigned int MK2_TIMEOUT_MS = 500;
enum { EUROLITE_PRO_FRAME_SIZE = 518 };

/*
@@ -149,7 +151,7 @@ bool EuroliteProThreadedSender::TransmitBuffer(libusb_device_handle *handle,
// not sure if this is fatal or not
OLA_WARN << "EurolitePro driver failed to transfer all data";
}
return r == 0;
return (r == 0);
}

// SynchronousEurolitePro
@@ -158,8 +160,9 @@ bool EuroliteProThreadedSender::TransmitBuffer(libusb_device_handle *handle,
SynchronousEurolitePro::SynchronousEurolitePro(
LibUsbAdaptor *adaptor,
libusb_device *usb_device,
const string &serial)
: EurolitePro(adaptor, usb_device, serial) {
const string &serial,
bool is_mk2)
: EurolitePro(adaptor, usb_device, serial, is_mk2) {
}

bool SynchronousEurolitePro::Init() {
@@ -176,6 +179,26 @@ bool SynchronousEurolitePro::Init() {
return false;
}

// USB-DMX512-PRO MK2: set baudrate to 250000
if (m_is_mk2) {
uint16_t divisor = 3000000 / 250000;
uint16_t value = divisor; // divisor & 0xFFFF
uint16_t index = (divisor >> 8) & 0xFF00;
int err = m_adaptor->ControlTransfer(
usb_handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE |
LIBUSB_ENDPOINT_OUT, // bmRequestType
MK2_SET_BAUD_RATE, // bRequest
value, // wValue
index, // wIndex
NULL, // data
0, // wLength
MK2_TIMEOUT_MS); // timeout
if (err) {
return false;
}
}

std::auto_ptr<EuroliteProThreadedSender> sender(
new EuroliteProThreadedSender(m_adaptor, m_usb_device, usb_handle));
if (!sender->Start()) {
@@ -194,8 +217,10 @@ bool SynchronousEurolitePro::SendDMX(const DmxBuffer &buffer) {
class EuroliteProAsyncUsbSender : public AsyncUsbSender {
public:
EuroliteProAsyncUsbSender(LibUsbAdaptor *adaptor,
libusb_device *usb_device)
: AsyncUsbSender(adaptor, usb_device) {
libusb_device *usb_device,
bool is_mk2)
: AsyncUsbSender(adaptor, usb_device),
m_is_mk2(is_mk2) {
}

~EuroliteProAsyncUsbSender() {
@@ -211,7 +236,31 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {
libusb_device_handle *usb_handle;
bool ok = m_adaptor->OpenDeviceAndClaimInterface(
m_usb_device, interface_number, &usb_handle);
return ok ? usb_handle : NULL;
if (!ok) {
return NULL;
}

// USB-DMX512-PRO MK2: set baudrate to 250000
if (m_is_mk2) {
uint16_t divisor = 3000000 / 250000;
uint16_t value = divisor; // divisor & 0xFFFF
uint16_t index = (divisor >> 8) & 0xFF00;
int err = m_adaptor->ControlTransfer(
usb_handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE |
LIBUSB_ENDPOINT_OUT, // bmRequestType
MK2_SET_BAUD_RATE, // bRequest
value, // wValue
index, // wIndex
NULL, // data
0, // wLength
MK2_TIMEOUT_MS); // timeout
if (err) {
return NULL;
}
}

return usb_handle;
}

bool PerformTransfer(const DmxBuffer &buffer) {
@@ -223,6 +272,7 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {

private:
uint8_t m_tx_frame[EUROLITE_PRO_FRAME_SIZE];
bool m_is_mk2;

DISALLOW_COPY_AND_ASSIGN(EuroliteProAsyncUsbSender);
};
@@ -233,9 +283,12 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {
AsynchronousEurolitePro::AsynchronousEurolitePro(
LibUsbAdaptor *adaptor,
libusb_device *usb_device,
const string &serial)
: EurolitePro(adaptor, usb_device, serial) {
m_sender.reset(new EuroliteProAsyncUsbSender(m_adaptor, usb_device));
const string &serial,
bool is_mk2)
: EurolitePro(adaptor, usb_device, serial, is_mk2) {
m_sender.reset(new EuroliteProAsyncUsbSender(m_adaptor,
usb_device,
m_is_mk2));
}

bool AsynchronousEurolitePro::Init() {
@@ -46,11 +46,14 @@ class EurolitePro : public SimpleWidget {
* @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of the widget.
* @param is_mk2 whether the widget is a mk 2 variant.
*/
EurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device,
const std::string &serial)
const std::string &serial,
bool is_mk2)
: SimpleWidget(adaptor, usb_device),
m_is_mk2(is_mk2),
m_serial(serial) {}

/**
@@ -61,6 +64,9 @@ class EurolitePro : public SimpleWidget {
return m_serial;
}

protected:
bool m_is_mk2;

private:
std::string m_serial;
};
@@ -78,10 +84,12 @@ class SynchronousEurolitePro: public EurolitePro {
* @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of the widget.
* @param is_mk2 whether the widget is a mk 2 variant.
*/
SynchronousEurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device,
const std::string &serial);
const std::string &serial,
bool is_mk2);

bool Init();

@@ -103,10 +111,12 @@ class AsynchronousEurolitePro: public EurolitePro {
* @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of the widget.
* @param is_mk2 whether the widget is a mk 2 variant.
*/
AsynchronousEurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device,
const std::string &serial);
const std::string &serial,
bool is_mk2);

bool Init();

@@ -32,30 +32,85 @@ namespace usbdmx {

using ola::usb::LibUsbAdaptor;

// "Eurolite USB-DMX512-PRO"
const char EuroliteProFactory::EXPECTED_MANUFACTURER[] = "Eurolite";
const char EuroliteProFactory::EXPECTED_PRODUCT[] = "Eurolite DMX512 Pro";
const uint16_t EuroliteProFactory::PRODUCT_ID = 0xfa63;
const uint16_t EuroliteProFactory::VENDOR_ID = 0x04d8;

// "Eurolite USB-DMX512-PRO MK2" (successor device introduced in late 2016)
const char EuroliteProFactory::EXPECTED_MANUFACTURER_MK2[] = "FTDI";
const char EuroliteProFactory::EXPECTED_PRODUCT_MK2[] = "FT232R USB UART";
const uint16_t EuroliteProFactory::PRODUCT_ID_MK2 = 0x6001;
const uint16_t EuroliteProFactory::VENDOR_ID_MK2 = 0x0403;

const char EuroliteProFactory::ENABLE_EUROLITE_MK2_KEY[] =
"enable_eurolite_mk2";

EuroliteProFactory::EuroliteProFactory(ola::usb::LibUsbAdaptor *adaptor,
Preferences *preferences)
: BaseWidgetFactory<class EurolitePro>("EuroliteProFactory"),
m_adaptor(adaptor),
m_enable_eurolite_mk2(IsEuroliteMk2Enabled(preferences)) {
}

bool EuroliteProFactory::IsEuroliteMk2Enabled(Preferences *preferences) {
bool enabled;
if (!StringToBool(preferences->GetValue(ENABLE_EUROLITE_MK2_KEY),
&enabled)) {
enabled = false;
}
return enabled;
}

bool EuroliteProFactory::DeviceAdded(
WidgetObserver *observer,
libusb_device *usb_device,
const struct libusb_device_descriptor &descriptor) {
if (descriptor.idVendor != VENDOR_ID || descriptor.idProduct != PRODUCT_ID) {
return false;
}
bool is_mk2 = false;

OLA_INFO << "Found a new EurolitePro device";
LibUsbAdaptor::DeviceInformation info;
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
return false;
}
// Eurolite USB-DMX512-PRO?
if (descriptor.idVendor == VENDOR_ID && descriptor.idProduct == PRODUCT_ID) {
OLA_INFO << "Found a new Eurolite USB-DMX512-PRO device";
LibUsbAdaptor::DeviceInformation info;
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
return false;
}

if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) {
return false;
}
if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) {
return false;
}

if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT, info)) {
if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT, info)) {
return false;
}

// Eurolite USB-DMX512-PRO MK2?
} else if (descriptor.idVendor == VENDOR_ID_MK2 &&
descriptor.idProduct == PRODUCT_ID_MK2) {
if (m_enable_eurolite_mk2) {
OLA_INFO << "Found a possible new Eurolite USB-DMX512-PRO MK2 device";
LibUsbAdaptor::DeviceInformation info;
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
return false;
}

if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER_MK2, info)) {
return false;
}

if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT_MK2, info)) {
return false;
}
is_mk2 = true;
} else {
OLA_INFO << "Connected FTDI device could be a Eurolite "
<< "USB-DMX512-PRO MK2 but was ignored, because "
<< ENABLE_EUROLITE_MK2_KEY << " was false.";
return false;
}
} else {
// Something else
return false;
}

@@ -74,10 +129,12 @@ bool EuroliteProFactory::DeviceAdded(
EurolitePro *widget = NULL;
if (FLAGS_use_async_libusb) {
widget = new AsynchronousEurolitePro(m_adaptor, usb_device,
serial_str.str());
serial_str.str(),
is_mk2);
} else {
widget = new SynchronousEurolitePro(m_adaptor, usb_device,
serial_str.str());
serial_str.str(),
is_mk2);
}
return AddWidget(observer, widget);
}
@@ -23,6 +23,7 @@

#include "libs/usb/LibUsbAdaptor.h"
#include "ola/base/Macro.h"
#include "olad/Preferences.h"
#include "plugins/usbdmx/EurolitePro.h"
#include "plugins/usbdmx/WidgetFactory.h"

@@ -35,22 +36,30 @@ namespace usbdmx {
*/
class EuroliteProFactory : public BaseWidgetFactory<class EurolitePro> {
public:
explicit EuroliteProFactory(ola::usb::LibUsbAdaptor *adaptor)
: BaseWidgetFactory<class EurolitePro>("EuroliteProFactory"),
m_adaptor(adaptor) {}
explicit EuroliteProFactory(ola::usb::LibUsbAdaptor *adaptor,
Preferences *preferences);

bool DeviceAdded(WidgetObserver *observer,
libusb_device *usb_device,
const struct libusb_device_descriptor &descriptor);

static bool IsEuroliteMk2Enabled(Preferences *preferences);

private:
ola::usb::LibUsbAdaptor *m_adaptor;
bool m_enable_eurolite_mk2;

static const uint16_t PRODUCT_ID;
static const uint16_t VENDOR_ID;
static const char EXPECTED_MANUFACTURER[];
static const char EXPECTED_PRODUCT[];

static const uint16_t PRODUCT_ID_MK2;
static const uint16_t VENDOR_ID_MK2;
static const char EXPECTED_MANUFACTURER_MK2[];
static const char EXPECTED_PRODUCT_MK2[];

static const char ENABLE_EUROLITE_MK2_KEY[];

DISALLOW_COPY_AND_ASSIGN(EuroliteProFactory);
};
@@ -7,7 +7,8 @@ This plugin supports various USB DMX devices including:
* AVLdiy D512
* DMXControl Projects e.V. Nodle U1
* DMXCreator 512 Basic
* Eurolite
* Eurolite USB-DMX512 PRO
* Eurolite USB-DMX512 PRO MK2 (when `enable_eurolite_mk2 = true`)
* Fadecandy
* ShowJockey SJ-DMX-U1
* Sunlite USBDMX2
@@ -20,6 +21,13 @@ This plugin supports various USB DMX devices including:
The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/
0 = No logging, 4 = Verbose debug.

`enable_eurolite_mk2 = {false,true}`
Whether to enable detection of the Eurolite USB-DMX512 PRO MK2.
Default = false. This device is indistinguishable from other devices
with an FTDI chip, and is therefore disabled by default. When enabled,
this plugin will conflict with the usbserial, StageProfi and FTDI USB DMX
plugins.

`nodle-<serial>-mode = {0,1,2,3,4,5,6,7}`
The mode for the Nodle U1 interface with serial number `<serial>` to operate
in. Default = 6
@@ -77,7 +77,8 @@ SyncPluginImpl::SyncPluginImpl(PluginAdaptor *plugin_adaptor,
m_widget_factories.push_back(new DMXCProjectsNodleU1Factory(&m_usb_adaptor,
m_plugin_adaptor, m_preferences));
m_widget_factories.push_back(new DMXCreator512BasicFactory(&m_usb_adaptor));
m_widget_factories.push_back(new EuroliteProFactory(&m_usb_adaptor));
m_widget_factories.push_back(new EuroliteProFactory(&m_usb_adaptor,
m_preferences));
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 SunliteFactory(&m_usb_adaptor));

0 comments on commit de24dd6

Please sign in to comment.
You can’t perform that action at this time.