Skip to content

Commit de24dd6

Browse files
authored
Merge branch 'master' into fix-get-dimmer-max
2 parents 81d7b21 + c6c3842 commit de24dd6

File tree

9 files changed

+186
-32
lines changed

9 files changed

+186
-32
lines changed

plugins/usbdmx/AsyncPluginImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ bool AsyncPluginImpl::Start() {
126126
m_preferences));
127127
m_widget_factories.push_back(new DMXCreator512BasicFactory(m_usb_adaptor));
128128
m_widget_factories.push_back(
129-
new EuroliteProFactory(m_usb_adaptor));
129+
new EuroliteProFactory(m_usb_adaptor, m_preferences));
130130
m_widget_factories.push_back(
131131
new JaRuleFactory(m_plugin_adaptor, m_usb_adaptor));
132132
m_widget_factories.push_back(

plugins/usbdmx/EurolitePro.cpp

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static const uint8_t DMX_LABEL = 6;
4646
static const uint8_t START_OF_MESSAGE = 0x7e;
4747
static const uint8_t END_OF_MESSAGE = 0xe7;
4848
static const unsigned char ENDPOINT = 0x02;
49+
static const uint8_t MK2_SET_BAUD_RATE = 0x03;
50+
static const unsigned int MK2_TIMEOUT_MS = 500;
4951
enum { EUROLITE_PRO_FRAME_SIZE = 518 };
5052

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

155157
// SynchronousEurolitePro
@@ -158,8 +160,9 @@ bool EuroliteProThreadedSender::TransmitBuffer(libusb_device_handle *handle,
158160
SynchronousEurolitePro::SynchronousEurolitePro(
159161
LibUsbAdaptor *adaptor,
160162
libusb_device *usb_device,
161-
const string &serial)
162-
: EurolitePro(adaptor, usb_device, serial) {
163+
const string &serial,
164+
bool is_mk2)
165+
: EurolitePro(adaptor, usb_device, serial, is_mk2) {
163166
}
164167

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

182+
// USB-DMX512-PRO MK2: set baudrate to 250000
183+
if (m_is_mk2) {
184+
uint16_t divisor = 3000000 / 250000;
185+
uint16_t value = divisor; // divisor & 0xFFFF
186+
uint16_t index = (divisor >> 8) & 0xFF00;
187+
int err = m_adaptor->ControlTransfer(
188+
usb_handle,
189+
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE |
190+
LIBUSB_ENDPOINT_OUT, // bmRequestType
191+
MK2_SET_BAUD_RATE, // bRequest
192+
value, // wValue
193+
index, // wIndex
194+
NULL, // data
195+
0, // wLength
196+
MK2_TIMEOUT_MS); // timeout
197+
if (err) {
198+
return false;
199+
}
200+
}
201+
179202
std::auto_ptr<EuroliteProThreadedSender> sender(
180203
new EuroliteProThreadedSender(m_adaptor, m_usb_device, usb_handle));
181204
if (!sender->Start()) {
@@ -194,8 +217,10 @@ bool SynchronousEurolitePro::SendDMX(const DmxBuffer &buffer) {
194217
class EuroliteProAsyncUsbSender : public AsyncUsbSender {
195218
public:
196219
EuroliteProAsyncUsbSender(LibUsbAdaptor *adaptor,
197-
libusb_device *usb_device)
198-
: AsyncUsbSender(adaptor, usb_device) {
220+
libusb_device *usb_device,
221+
bool is_mk2)
222+
: AsyncUsbSender(adaptor, usb_device),
223+
m_is_mk2(is_mk2) {
199224
}
200225

201226
~EuroliteProAsyncUsbSender() {
@@ -211,7 +236,31 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {
211236
libusb_device_handle *usb_handle;
212237
bool ok = m_adaptor->OpenDeviceAndClaimInterface(
213238
m_usb_device, interface_number, &usb_handle);
214-
return ok ? usb_handle : NULL;
239+
if (!ok) {
240+
return NULL;
241+
}
242+
243+
// USB-DMX512-PRO MK2: set baudrate to 250000
244+
if (m_is_mk2) {
245+
uint16_t divisor = 3000000 / 250000;
246+
uint16_t value = divisor; // divisor & 0xFFFF
247+
uint16_t index = (divisor >> 8) & 0xFF00;
248+
int err = m_adaptor->ControlTransfer(
249+
usb_handle,
250+
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE |
251+
LIBUSB_ENDPOINT_OUT, // bmRequestType
252+
MK2_SET_BAUD_RATE, // bRequest
253+
value, // wValue
254+
index, // wIndex
255+
NULL, // data
256+
0, // wLength
257+
MK2_TIMEOUT_MS); // timeout
258+
if (err) {
259+
return NULL;
260+
}
261+
}
262+
263+
return usb_handle;
215264
}
216265

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

224273
private:
225274
uint8_t m_tx_frame[EUROLITE_PRO_FRAME_SIZE];
275+
bool m_is_mk2;
226276

227277
DISALLOW_COPY_AND_ASSIGN(EuroliteProAsyncUsbSender);
228278
};
@@ -233,9 +283,12 @@ class EuroliteProAsyncUsbSender : public AsyncUsbSender {
233283
AsynchronousEurolitePro::AsynchronousEurolitePro(
234284
LibUsbAdaptor *adaptor,
235285
libusb_device *usb_device,
236-
const string &serial)
237-
: EurolitePro(adaptor, usb_device, serial) {
238-
m_sender.reset(new EuroliteProAsyncUsbSender(m_adaptor, usb_device));
286+
const string &serial,
287+
bool is_mk2)
288+
: EurolitePro(adaptor, usb_device, serial, is_mk2) {
289+
m_sender.reset(new EuroliteProAsyncUsbSender(m_adaptor,
290+
usb_device,
291+
m_is_mk2));
239292
}
240293

241294
bool AsynchronousEurolitePro::Init() {

plugins/usbdmx/EurolitePro.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,14 @@ class EurolitePro : public SimpleWidget {
4646
* @param adaptor the LibUsbAdaptor to use.
4747
* @param usb_device the libusb_device to use for the widget.
4848
* @param serial the serial number of the widget.
49+
* @param is_mk2 whether the widget is a mk 2 variant.
4950
*/
5051
EurolitePro(ola::usb::LibUsbAdaptor *adaptor,
5152
libusb_device *usb_device,
52-
const std::string &serial)
53+
const std::string &serial,
54+
bool is_mk2)
5355
: SimpleWidget(adaptor, usb_device),
56+
m_is_mk2(is_mk2),
5457
m_serial(serial) {}
5558

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

67+
protected:
68+
bool m_is_mk2;
69+
6470
private:
6571
std::string m_serial;
6672
};
@@ -78,10 +84,12 @@ class SynchronousEurolitePro: public EurolitePro {
7884
* @param adaptor the LibUsbAdaptor to use.
7985
* @param usb_device the libusb_device to use for the widget.
8086
* @param serial the serial number of the widget.
87+
* @param is_mk2 whether the widget is a mk 2 variant.
8188
*/
8289
SynchronousEurolitePro(ola::usb::LibUsbAdaptor *adaptor,
8390
libusb_device *usb_device,
84-
const std::string &serial);
91+
const std::string &serial,
92+
bool is_mk2);
8593

8694
bool Init();
8795

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

111121
bool Init();
112122

plugins/usbdmx/EuroliteProFactory.cpp

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,85 @@ namespace usbdmx {
3232

3333
using ola::usb::LibUsbAdaptor;
3434

35+
// "Eurolite USB-DMX512-PRO"
3536
const char EuroliteProFactory::EXPECTED_MANUFACTURER[] = "Eurolite";
3637
const char EuroliteProFactory::EXPECTED_PRODUCT[] = "Eurolite DMX512 Pro";
3738
const uint16_t EuroliteProFactory::PRODUCT_ID = 0xfa63;
3839
const uint16_t EuroliteProFactory::VENDOR_ID = 0x04d8;
3940

41+
// "Eurolite USB-DMX512-PRO MK2" (successor device introduced in late 2016)
42+
const char EuroliteProFactory::EXPECTED_MANUFACTURER_MK2[] = "FTDI";
43+
const char EuroliteProFactory::EXPECTED_PRODUCT_MK2[] = "FT232R USB UART";
44+
const uint16_t EuroliteProFactory::PRODUCT_ID_MK2 = 0x6001;
45+
const uint16_t EuroliteProFactory::VENDOR_ID_MK2 = 0x0403;
46+
47+
const char EuroliteProFactory::ENABLE_EUROLITE_MK2_KEY[] =
48+
"enable_eurolite_mk2";
49+
50+
EuroliteProFactory::EuroliteProFactory(ola::usb::LibUsbAdaptor *adaptor,
51+
Preferences *preferences)
52+
: BaseWidgetFactory<class EurolitePro>("EuroliteProFactory"),
53+
m_adaptor(adaptor),
54+
m_enable_eurolite_mk2(IsEuroliteMk2Enabled(preferences)) {
55+
}
56+
57+
bool EuroliteProFactory::IsEuroliteMk2Enabled(Preferences *preferences) {
58+
bool enabled;
59+
if (!StringToBool(preferences->GetValue(ENABLE_EUROLITE_MK2_KEY),
60+
&enabled)) {
61+
enabled = false;
62+
}
63+
return enabled;
64+
}
65+
4066
bool EuroliteProFactory::DeviceAdded(
4167
WidgetObserver *observer,
4268
libusb_device *usb_device,
4369
const struct libusb_device_descriptor &descriptor) {
44-
if (descriptor.idVendor != VENDOR_ID || descriptor.idProduct != PRODUCT_ID) {
45-
return false;
46-
}
70+
bool is_mk2 = false;
4771

48-
OLA_INFO << "Found a new EurolitePro device";
49-
LibUsbAdaptor::DeviceInformation info;
50-
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
51-
return false;
52-
}
72+
// Eurolite USB-DMX512-PRO?
73+
if (descriptor.idVendor == VENDOR_ID && descriptor.idProduct == PRODUCT_ID) {
74+
OLA_INFO << "Found a new Eurolite USB-DMX512-PRO device";
75+
LibUsbAdaptor::DeviceInformation info;
76+
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
77+
return false;
78+
}
5379

54-
if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) {
55-
return false;
56-
}
80+
if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER, info)) {
81+
return false;
82+
}
5783

58-
if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT, info)) {
84+
if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT, info)) {
85+
return false;
86+
}
87+
88+
// Eurolite USB-DMX512-PRO MK2?
89+
} else if (descriptor.idVendor == VENDOR_ID_MK2 &&
90+
descriptor.idProduct == PRODUCT_ID_MK2) {
91+
if (m_enable_eurolite_mk2) {
92+
OLA_INFO << "Found a possible new Eurolite USB-DMX512-PRO MK2 device";
93+
LibUsbAdaptor::DeviceInformation info;
94+
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
95+
return false;
96+
}
97+
98+
if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER_MK2, info)) {
99+
return false;
100+
}
101+
102+
if (!m_adaptor->CheckProduct(EXPECTED_PRODUCT_MK2, info)) {
103+
return false;
104+
}
105+
is_mk2 = true;
106+
} else {
107+
OLA_INFO << "Connected FTDI device could be a Eurolite "
108+
<< "USB-DMX512-PRO MK2 but was ignored, because "
109+
<< ENABLE_EUROLITE_MK2_KEY << " was false.";
110+
return false;
111+
}
112+
} else {
113+
// Something else
59114
return false;
60115
}
61116

@@ -74,10 +129,12 @@ bool EuroliteProFactory::DeviceAdded(
74129
EurolitePro *widget = NULL;
75130
if (FLAGS_use_async_libusb) {
76131
widget = new AsynchronousEurolitePro(m_adaptor, usb_device,
77-
serial_str.str());
132+
serial_str.str(),
133+
is_mk2);
78134
} else {
79135
widget = new SynchronousEurolitePro(m_adaptor, usb_device,
80-
serial_str.str());
136+
serial_str.str(),
137+
is_mk2);
81138
}
82139
return AddWidget(observer, widget);
83140
}

plugins/usbdmx/EuroliteProFactory.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "libs/usb/LibUsbAdaptor.h"
2525
#include "ola/base/Macro.h"
26+
#include "olad/Preferences.h"
2627
#include "plugins/usbdmx/EurolitePro.h"
2728
#include "plugins/usbdmx/WidgetFactory.h"
2829

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

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

46+
static bool IsEuroliteMk2Enabled(Preferences *preferences);
47+
4648
private:
4749
ola::usb::LibUsbAdaptor *m_adaptor;
50+
bool m_enable_eurolite_mk2;
4851

4952
static const uint16_t PRODUCT_ID;
5053
static const uint16_t VENDOR_ID;
5154
static const char EXPECTED_MANUFACTURER[];
5255
static const char EXPECTED_PRODUCT[];
5356

57+
static const uint16_t PRODUCT_ID_MK2;
58+
static const uint16_t VENDOR_ID_MK2;
59+
static const char EXPECTED_MANUFACTURER_MK2[];
60+
static const char EXPECTED_PRODUCT_MK2[];
61+
62+
static const char ENABLE_EUROLITE_MK2_KEY[];
5463

5564
DISALLOW_COPY_AND_ASSIGN(EuroliteProFactory);
5665
};

plugins/usbdmx/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ This plugin supports various USB DMX devices including:
77
* AVLdiy D512
88
* DMXControl Projects e.V. Nodle U1
99
* DMXCreator 512 Basic
10-
* Eurolite
10+
* Eurolite USB-DMX512 PRO
11+
* Eurolite USB-DMX512 PRO MK2 (when `enable_eurolite_mk2 = true`)
1112
* Fadecandy
1213
* ShowJockey SJ-DMX-U1
1314
* Sunlite USBDMX2
@@ -20,6 +21,13 @@ This plugin supports various USB DMX devices including:
2021
The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/
2122
0 = No logging, 4 = Verbose debug.
2223

24+
`enable_eurolite_mk2 = {false,true}`
25+
Whether to enable detection of the Eurolite USB-DMX512 PRO MK2.
26+
Default = false. This device is indistinguishable from other devices
27+
with an FTDI chip, and is therefore disabled by default. When enabled,
28+
this plugin will conflict with the usbserial, StageProfi and FTDI USB DMX
29+
plugins.
30+
2331
`nodle-<serial>-mode = {0,1,2,3,4,5,6,7}`
2432
The mode for the Nodle U1 interface with serial number `<serial>` to operate
2533
in. Default = 6

plugins/usbdmx/SyncPluginImpl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ SyncPluginImpl::SyncPluginImpl(PluginAdaptor *plugin_adaptor,
7777
m_widget_factories.push_back(new DMXCProjectsNodleU1Factory(&m_usb_adaptor,
7878
m_plugin_adaptor, m_preferences));
7979
m_widget_factories.push_back(new DMXCreator512BasicFactory(&m_usb_adaptor));
80-
m_widget_factories.push_back(new EuroliteProFactory(&m_usb_adaptor));
80+
m_widget_factories.push_back(new EuroliteProFactory(&m_usb_adaptor,
81+
m_preferences));
8182
m_widget_factories.push_back(new ScanlimeFadecandyFactory(&m_usb_adaptor));
8283
m_widget_factories.push_back(new ShowJockeyDMXU1Factory(&m_usb_adaptor));
8384
m_widget_factories.push_back(new SunliteFactory(&m_usb_adaptor));

0 commit comments

Comments
 (0)