-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added DMXCreator 512 Basic USB interface #1136
Added DMXCreator 512 Basic USB interface #1136
Conversation
see http://www.dmx512.ch/512.html I reverse-engineered the USB protocol using WireShark and USBPcap. This is my first try, so there may be some functions that I didn't implement or that could be better, please just let me know. DMXCreator sends two URB packets for each change: 1. A constant byte string to endpoint 1 that indicates new data. 2. The actual DMX data to endpoint 2. It currently only supports 256 channels, I may work on that later. Also, there is a bug that lets it consume way too much memory in synchronous libusb mode until it eventually gets killed.
There is one more bug: It doesn't handle unplugging correctly so the next time it gets plugged in, it refuses to connect because of the missing serial number (there can always only be one DMXCreator device at a time). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments so far.
We're also about to merge #1134 which will need a bit of minor tidying on your side to fix.
@@ -56,7 +56,7 @@ bool UsbDmxPlugin::StartHook() { | |||
} | |||
|
|||
unsigned int debug_level; | |||
if (!StringToInt(m_preferences->GetValue(LIBUSB_DEBUG_LEVEL_KEY) , | |||
if (!StringToInt(m_preferences->GetValue(LIBUSB_DEBUG_LEVEL_KEY), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot!
I think the unplugging bug will be because m_missing_serial_number never gets reset when the serial number less widget gets unplugged. I suspect this bug affects all the widgets with the same code. |
I'd imagine you send a different constant to endpoint 1 to send the other half of the universe, or perhaps just a second packet to endpoint 2 before you send the endpoint 1 data (i.e. sending to endpoint 1 may reset the slot counter back to 0). |
Hopefully the synchronous issue can be fixed, if not, it probably needs to be disabled for the moment. |
The other PR is in, so you can resync this. |
* allow all 512 channels to be sent * disabled synchronous mode for now * made timeout much shorter * changed display name
It was exactly as you said: Just send two packets after another to endpoint 2. But I also had to change the constant that is sent to endpoint 1. It took me quite a while to figure that out 🙈 The unplugging bug and the synchronous mode issue unfortunately do both still exist. I'll look into them soon. |
Please can you add the device to the list in plugins/usbdmx/UsbDmxPlugin.h too. |
} | ||
|
||
bool PerformTransfer(const DmxBuffer &buffer) { | ||
// if we only wanted to send the first half, the last byte would be 0x01 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it you've not worked out what the other bytes in the packet do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not. I just have this one device for testing, I guess the other DMXCreator dongles use other bytes.
OLA_INFO << "Found a new DMXCreator device"; | ||
// Unfortunately, DMXCreator devices don't provide any additional information | ||
// that identify them. So we have to stick with just testing vendor and | ||
// product ids. Also, since DMXCreator devices don't have serial numbers and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know for certain that none have serial numbers?
The m_adaptor->GetDeviceInfo(usb_device, descriptor, &info) call ought to succeed if the device is present, even if it returns no other info, so you could do the following still, and just remove the vendor/device name checks:
LibUsbAdaptor::DeviceInformation info;
if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) {
return false;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll do that. I'm not completely sure that none of those devices have serial numbers but I think they don't since they do not even return valid manufacturer / product names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. As you say, I suspect they're unlikely to have serial numbers, but it would be a shame to be missing the functionality if they did (given it's already been written).
Can you also add the 512 Basic bit to the filenames too please, given they already have other interfaces we might want to support in future. |
* rename "DMXCreator" and "DMXCreator 512 Basic" to "DMXCreator512Basic" to be consistent * add serial check again * more minor fixes
causing doxygen to fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more minor comments.
Everything should be fine now 😉 |
return true; | ||
} | ||
|
||
m_dmx_buffer = new DmxBuffer(buffer); // force copy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're copying the buffer just to see if it's changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a better way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was partly just a comment that you could use it for the buffer.Get/GetRange calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly don't see an advantage in that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that I can immediately think of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No specific advantage, but it would just mean you sort of take control of that data and only use that data in the plugin. You've currently got an odd mix of the locally cached and freshly fed in data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, there is an improvement, you can switch to m_dmx_buffer = buffer; Due to some magic we do in the background, it will copy the data if it needs to, but otherwise just leave it as a pointer.
Travis failed due to the GitHub outage, I guess. |
} | ||
|
||
bytes_sent = 0; | ||
r = m_adaptor->BulkTransfer(handle, ENDPOINT_2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move this code into a function since it's repeated 3 times.
Sorry, I pushed by accident. Just ignore this commit until I comment again. |
Now the BulkTransfer works as before. The size was wrong. |
Travis' PyChecker failed again due to network outage. Don't know if it was Sourceforge or Travis itself. At least it was not me ;) Anyway, that test has nothing to do with my changes and the compiler tests come out well. |
Any updates on this? I believe I have addressed all of your requested changes @peternewman @nomis52 |
Hi @FloEdelmann , sorry I've been rather busy, I'll try and look in the next day or two. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few more changes please.
@nomis52 any final comments from you? |
Yay, it's done! 🎉 |
Yep thanks for all your hard work @FloEdelmann , now onto the next one... |
see http://www.dmx512.ch/512.html
I reverse-engineered the USB protocol using WireShark and USBPcap. This is my first try, so there may be some functions that I didn't implement or that could be better, please just let me know.
DMXCreator sends two URB packets for each change:
It currently only supports 256 channels, I may work on that later.(Fixed in df44d5a)Also, there is a bug that lets it consume way too much memory in synchronous libusb mode until it eventually gets killed.