Reverse engineering a USB peripheral driver for the Owon scope

As part of this router project, I need to understand USB at a low-level – for driving a MAX3421 controller.   And for some months now, I have been meaning to look at a digital storage oscilloscope made by Owon.  It is the PDS5022s model which can be connected to a PC over a USB link.

Unfortunately, the Owon software although written in Java is wrapped up in a Windows-only executable.   I want to use the scope in Linux, and the binary won’t even run in Wine, nor can I unwrap it to get to the Java classes.

So, there lies the dilemma. I needed to understand USB, and I wanted to reverse engineering the USB peripheral driver for the digital scope.  Here we see two birds and one stone!

With the help of a USB sniffer that runs on Windows, the libusb C library, gcc, khexedit, usbmon and some sticky-backed plastic, I finally got there..   a working userspace Linux driver for the Owon.  At a guess, the code should also work for other scopes in the Owon range.  Once I’ve debugged it a bit, I will post up the source.

[michael@epox Debug]$ ./owondump test5.bin

..Initialising libUSB
..Finding USB buses
..Searching buses for Owon
..Found an Owon device 5345:1234 on bus 001
..Attempting USB lock on device  5345:1234
..Trying to claim interface 0 of 5345:1234
..Successfully claimed interface 0 to 5345:1234
..Attempting to get the Device Descriptor
..Successfully obtained device descriptor!
..Attempting to bulk write start command to device...
..Successful bulk write of 0005h bytes!
..Attempting to bulk read 000ch bytes from device...
..Successful bulk read of 000ch bytes! :
        00000000: e1 d7 00 00 8d d4 2d 21 00 00 00 00
..Attempting to malloc read buffer space of 0000d7e1h bytes
..Successful malloc!
..Owon ready to bulk transfer 0000d7e1h bytes
..Attempting to bulk read 0000d7e1h bytes from device...
..Successful bulk read of 0000d7e1h bytes! :
..Hexdump of CH1 header :
        00000000: 53 50 42 56 30 31 e1 d7 00 00 43 48 31 04 31 00
        00000001: 00 6a 18 00 00 6a 18 00 00 00 00 00 00 11 00 00
        00000002: 00 fe ff ff ff 02 00 00 00 00 00 00 00 00 00 80
        00000003: 40 cb 17 48 42 6c 2d 9c 46 cd cc cc 3e 2a 00 29
..Channel Settings :
 channel name: CH1
 vertical sens: 10mV
 timebase: 0.0025s

 channel name: CH2
 vertical sens: 20mV
 timebase: 0.0025s

 channel name: CHA
 vertical sens: 10mV
 timebase: 0.01s

 channel name: CHB
 vertical sens: 10mV
 timebase: 0.005s

 channel name: CHC
 vertical sens: 20mV
 timebase: 0.01s
..Successfully opened file 'test5.bin'!
..Successfully written 55265 bytes to file test5.bin
..Attempting to release interface 0
..Successful release of interface 0!
[michael@epox Debug]$

owon bitmap using linux driver
Waveform bitmap downloaded using Linux driver for Owon

7 Responses to “Reverse engineering a USB peripheral driver for the Owon scope”

  1. Nice job! We sell Owon scopes in USA and if we get Linux inquirers, we’ll definitely point them to your page!

    Kind regards,

    Alan Lowne
    CEO
    Saelig Co. Inc.
    http://www.saelig.com

  2. Hi, I made a port of your driver to Win32 platform, also I made export to SVG format, chcek it here: http://gabonator.yweb.sk/sim/download/sources/Owon%20PDS5022S%20driver/samples/

    • Great stuff Gabriel!

      The SVG traces look magnificent! The memory leaks in my code sound interesting too! Where have you found them?! Please join the driver project if you have the time!

      Cheers,
      Michael

  3. Hello,

    i have Owon PDS6062. Your utility downloads binary data correct, i validate it in original DS Wave running under Wine, but in exported text data are wrong values if zero voltage is changed and amplitude is enough big …

    I tried repair it, but only with partially success. For example, when i had zero at position -3.0V and i sampled some TTL signal (Upp -0.4 to 3.3V), voltage range 500mV, then samples bigger than some value was converted incorrect (maybe bigger than 2V? i don’t know exactly).

    Originally you had this code
    fprintf(fpout, “\t\t%5.1f”, (short int) *ptr[i] * headers[i].vertSensitivity * 0.04);

    I replaced it with
    if (*ptr[i] < -32)
    tmp = (double) *ptr[i] + 255;
    else
    tmp = (double) *ptr[i];

    fprintf(fpout, "\t\t%5.1f", tmp * headers[i].vertSensitivity * 0.04);

    It helps, but only for this case I think, somewhere in binary data must be information about this setting and this must be applied in conversion.

  4. Nice work!

    Meanwhile it is 1012 but this is still almost up to date for the new scopes as well.
    I just bought an SDS8202 (200 MHz 2 GS/s scope with 2 channels). The software is still … how do I say this nicely … not finished.
    So I decided to reverse engineer the .bin wave file format just a day before seeing this blog. I have progressed a bit further thanks to you and decided to put the SDS8202 version of the wave file on my website as well.
    If someone with an SDS scope stumbles upon this page he/she might find more info here: http://bikealive.nl/owon-bin-file-format.html

    • ee07m060 Says:

      Good stuff! Owon did finally release the docs. Not so well translated so pretty hard to read. Maybe you can understand them better though?!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.