Skip to content

Commit

Permalink
Merge branch 'master' into fix-get-dimmer-max
Browse files Browse the repository at this point in the history
  • Loading branch information
peternewman committed Jun 29, 2019
2 parents 81d7b21 + c6c3842 commit de24dd6
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 32 deletions.
2 changes: 1 addition & 1 deletion plugins/usbdmx/AsyncPluginImpl.cpp
Expand Up @@ -126,7 +126,7 @@ bool AsyncPluginImpl::Start() {
m_preferences)); m_preferences));
m_widget_factories.push_back(new DMXCreator512BasicFactory(m_usb_adaptor)); m_widget_factories.push_back(new DMXCreator512BasicFactory(m_usb_adaptor));
m_widget_factories.push_back( m_widget_factories.push_back(
new EuroliteProFactory(m_usb_adaptor)); new EuroliteProFactory(m_usb_adaptor, m_preferences));
m_widget_factories.push_back( m_widget_factories.push_back(
new JaRuleFactory(m_plugin_adaptor, m_usb_adaptor)); new JaRuleFactory(m_plugin_adaptor, m_usb_adaptor));
m_widget_factories.push_back( m_widget_factories.push_back(
Expand Down
71 changes: 62 additions & 9 deletions plugins/usbdmx/EurolitePro.cpp
Expand Up @@ -46,6 +46,8 @@ static const uint8_t DMX_LABEL = 6;
static const uint8_t START_OF_MESSAGE = 0x7e; static const uint8_t START_OF_MESSAGE = 0x7e;
static const uint8_t END_OF_MESSAGE = 0xe7; static const uint8_t END_OF_MESSAGE = 0xe7;
static const unsigned char ENDPOINT = 0x02; 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 }; enum { EUROLITE_PRO_FRAME_SIZE = 518 };


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


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


bool SynchronousEurolitePro::Init() { bool SynchronousEurolitePro::Init() {
Expand All @@ -176,6 +179,26 @@ bool SynchronousEurolitePro::Init() {
return false; 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( std::auto_ptr<EuroliteProThreadedSender> sender(
new EuroliteProThreadedSender(m_adaptor, m_usb_device, usb_handle)); new EuroliteProThreadedSender(m_adaptor, m_usb_device, usb_handle));
if (!sender->Start()) { if (!sender->Start()) {
Expand All @@ -194,8 +217,10 @@ bool SynchronousEurolitePro::SendDMX(const DmxBuffer &buffer) {
class EuroliteProAsyncUsbSender : public AsyncUsbSender { class EuroliteProAsyncUsbSender : public AsyncUsbSender {
public: public:
EuroliteProAsyncUsbSender(LibUsbAdaptor *adaptor, EuroliteProAsyncUsbSender(LibUsbAdaptor *adaptor,
libusb_device *usb_device) libusb_device *usb_device,
: AsyncUsbSender(adaptor, usb_device) { bool is_mk2)
: AsyncUsbSender(adaptor, usb_device),
m_is_mk2(is_mk2) {
} }


~EuroliteProAsyncUsbSender() { ~EuroliteProAsyncUsbSender() {
Expand All @@ -211,7 +236,31 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {
libusb_device_handle *usb_handle; libusb_device_handle *usb_handle;
bool ok = m_adaptor->OpenDeviceAndClaimInterface( bool ok = m_adaptor->OpenDeviceAndClaimInterface(
m_usb_device, interface_number, &usb_handle); 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) { bool PerformTransfer(const DmxBuffer &buffer) {
Expand All @@ -223,6 +272,7 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {


private: private:
uint8_t m_tx_frame[EUROLITE_PRO_FRAME_SIZE]; uint8_t m_tx_frame[EUROLITE_PRO_FRAME_SIZE];
bool m_is_mk2;


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


bool AsynchronousEurolitePro::Init() { bool AsynchronousEurolitePro::Init() {
Expand Down
16 changes: 13 additions & 3 deletions plugins/usbdmx/EurolitePro.h
Expand Up @@ -46,11 +46,14 @@ class EurolitePro : public SimpleWidget {
* @param adaptor the LibUsbAdaptor to use. * @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget. * @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of 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, EurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device, libusb_device *usb_device,
const std::string &serial) const std::string &serial,
bool is_mk2)
: SimpleWidget(adaptor, usb_device), : SimpleWidget(adaptor, usb_device),
m_is_mk2(is_mk2),
m_serial(serial) {} m_serial(serial) {}


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


protected:
bool m_is_mk2;

private: private:
std::string m_serial; std::string m_serial;
}; };
Expand All @@ -78,10 +84,12 @@ class SynchronousEurolitePro: public EurolitePro {
* @param adaptor the LibUsbAdaptor to use. * @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget. * @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of 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, SynchronousEurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device, libusb_device *usb_device,
const std::string &serial); const std::string &serial,
bool is_mk2);


bool Init(); bool Init();


Expand All @@ -103,10 +111,12 @@ class AsynchronousEurolitePro: public EurolitePro {
* @param adaptor the LibUsbAdaptor to use. * @param adaptor the LibUsbAdaptor to use.
* @param usb_device the libusb_device to use for the widget. * @param usb_device the libusb_device to use for the widget.
* @param serial the serial number of 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, AsynchronousEurolitePro(ola::usb::LibUsbAdaptor *adaptor,
libusb_device *usb_device, libusb_device *usb_device,
const std::string &serial); const std::string &serial,
bool is_mk2);


bool Init(); bool Init();


Expand Down
85 changes: 71 additions & 14 deletions plugins/usbdmx/EuroliteProFactory.cpp
Expand Up @@ -32,30 +32,85 @@ namespace usbdmx {


using ola::usb::LibUsbAdaptor; using ola::usb::LibUsbAdaptor;


// "Eurolite USB-DMX512-PRO"
const char EuroliteProFactory::EXPECTED_MANUFACTURER[] = "Eurolite"; const char EuroliteProFactory::EXPECTED_MANUFACTURER[] = "Eurolite";
const char EuroliteProFactory::EXPECTED_PRODUCT[] = "Eurolite DMX512 Pro"; const char EuroliteProFactory::EXPECTED_PRODUCT[] = "Eurolite DMX512 Pro";
const uint16_t EuroliteProFactory::PRODUCT_ID = 0xfa63; const uint16_t EuroliteProFactory::PRODUCT_ID = 0xfa63;
const uint16_t EuroliteProFactory::VENDOR_ID = 0x04d8; 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( bool EuroliteProFactory::DeviceAdded(
WidgetObserver *observer, WidgetObserver *observer,
libusb_device *usb_device, libusb_device *usb_device,
const struct libusb_device_descriptor &descriptor) { const struct libusb_device_descriptor &descriptor) {
if (descriptor.idVendor != VENDOR_ID || descriptor.idProduct != PRODUCT_ID) { bool is_mk2 = false;
return false;
}


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


if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) { if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) {
return false; 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; return false;
} }


Expand All @@ -74,10 +129,12 @@ bool EuroliteProFactory::DeviceAdded(
EurolitePro *widget = NULL; EurolitePro *widget = NULL;
if (FLAGS_use_async_libusb) { if (FLAGS_use_async_libusb) {
widget = new AsynchronousEurolitePro(m_adaptor, usb_device, widget = new AsynchronousEurolitePro(m_adaptor, usb_device,
serial_str.str()); serial_str.str(),
is_mk2);
} else { } else {
widget = new SynchronousEurolitePro(m_adaptor, usb_device, widget = new SynchronousEurolitePro(m_adaptor, usb_device,
serial_str.str()); serial_str.str(),
is_mk2);
} }
return AddWidget(observer, widget); return AddWidget(observer, widget);
} }
Expand Down
15 changes: 12 additions & 3 deletions plugins/usbdmx/EuroliteProFactory.h
Expand Up @@ -23,6 +23,7 @@


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


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


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


static bool IsEuroliteMk2Enabled(Preferences *preferences);

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


static const uint16_t PRODUCT_ID; static const uint16_t PRODUCT_ID;
static const uint16_t VENDOR_ID; static const uint16_t VENDOR_ID;
static const char EXPECTED_MANUFACTURER[]; static const char EXPECTED_MANUFACTURER[];
static const char EXPECTED_PRODUCT[]; 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); DISALLOW_COPY_AND_ASSIGN(EuroliteProFactory);
}; };
Expand Down
10 changes: 9 additions & 1 deletion plugins/usbdmx/README.md
Expand Up @@ -7,7 +7,8 @@ This plugin supports various USB DMX devices including:
* AVLdiy D512 * AVLdiy D512
* DMXControl Projects e.V. Nodle U1 * DMXControl Projects e.V. Nodle U1
* DMXCreator 512 Basic * DMXCreator 512 Basic
* Eurolite * Eurolite USB-DMX512 PRO
* Eurolite USB-DMX512 PRO MK2 (when `enable_eurolite_mk2 = true`)
* Fadecandy * Fadecandy
* ShowJockey SJ-DMX-U1 * ShowJockey SJ-DMX-U1
* Sunlite USBDMX2 * Sunlite USBDMX2
Expand All @@ -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/ The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/
0 = No logging, 4 = Verbose debug. 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}` `nodle-<serial>-mode = {0,1,2,3,4,5,6,7}`
The mode for the Nodle U1 interface with serial number `<serial>` to operate The mode for the Nodle U1 interface with serial number `<serial>` to operate
in. Default = 6 in. Default = 6
Expand Down
3 changes: 2 additions & 1 deletion plugins/usbdmx/SyncPluginImpl.cpp
Expand Up @@ -77,7 +77,8 @@ SyncPluginImpl::SyncPluginImpl(PluginAdaptor *plugin_adaptor,
m_widget_factories.push_back(new DMXCProjectsNodleU1Factory(&m_usb_adaptor, m_widget_factories.push_back(new DMXCProjectsNodleU1Factory(&m_usb_adaptor,
m_plugin_adaptor, m_preferences)); m_plugin_adaptor, m_preferences));
m_widget_factories.push_back(new DMXCreator512BasicFactory(&m_usb_adaptor)); 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 ScanlimeFadecandyFactory(&m_usb_adaptor));
m_widget_factories.push_back(new ShowJockeyDMXU1Factory(&m_usb_adaptor)); m_widget_factories.push_back(new ShowJockeyDMXU1Factory(&m_usb_adaptor));
m_widget_factories.push_back(new SunliteFactory(&m_usb_adaptor)); m_widget_factories.push_back(new SunliteFactory(&m_usb_adaptor));
Expand Down

0 comments on commit de24dd6

Please sign in to comment.