Skip to content

taligentx/ZeeTweak

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ZeeTweak

ZeeTweak is a combination of firmware modifications and a companion zeetweak.py tool for the Zeeweii DSO3D12 oscilloscope, including:

  • Saved waveform download: Capture screenshot data via serial and render new high quality screenshots, text reports, and CSV data for use with applications like sigrok PulseView.
  • Arbitrary signal generator waveforms: Add new waveforms to the firmware
  • Graphics: New fonts, images, and home screen with multiple background options
  • UI tweaks: Screenshot counter repositioned, CH2 50% auto-set level centered
  • Sample buffer download: Capture and extract the secret buffer dump mode (up to 60k samples)

Zeeweii_DSO3D12_mod_v3.1

Waveform capture and screenshot render:

ZeeTweak_Screenshot_Capture

The provided example firmware has all mods applied, see Flashing below to apply the firmware.

  • To customize the firmware, place the desired mod files in a directory and use FLSTweak to generate a new firmware file.

Notes

  • Most UI mods in this repo cover resources that are directly stored in the firmware (not part of the compiled code), so images are altered but not functionally changed.
  • With release 4.x, some mods are based on reverse engineering of the firmware code (screenshot transfer, arbitrary waveforms, UI tweaks), which opens up the possibility of more functional changes. See the Ghidra files section below.
  • Since UI preferences are highly subjective, post an Issue or Pull Request for what you'd like to see - there is plenty of room for improvement. Discussion and (especially) contributions are welcome!

Release Notes

  • 4.1
    • New: Cursors measurements for rendered screenshots
    • New: CH2 50% auto-set level to 0 (originally offset by a few pixels)
    • New: Generate waveform CSV files for other applications
    • New: Support for DSO2512G screenshot data files (requires modified firmware)
    • Updated: Ghidra project 0.3 - all functions are now labeled!
    • Fixed: Windows serial port handling
    • Fixed: Voltage calculations for probes x1/x100 modes
  • 4.0
    • New: zeetweak.py
      • Screenshot data capture and rendering to new images with matplotlib
      • Arbitrary signal generator waveforms
      • Buffer dump capture (via secret debug mode)
    • New: Screenshot counter UI repositioned, no longer obscures waveforms or cursor measurements
    • Updated: Home screen icons
  • 3.2
    • New: Zeeweii firmware 3.0.7
    • New: image for the new DMM side menu (press Menu in full-screen DMM mode)
    • New: images for the new channel math menu (long-press Menu in scope mode)
    • Updated: images for the DMM mode selection menu
    • Updated: flashing with wm-tools
  • 3.1
    • New: zrle2bmp.py tool to convert Zeeweii-custom RLE compressed images
    • New: images from @Dmitur: sig. gen. numbers, trigger edge icon
    • New: images for channel level icon, trigger icon
    • Updated: measurement label background
    • Updated: menu display setting for persistence relabeled from 1s to 3s based on measured fade time
  • 3.0
    • New bitmaps for most UI elements
    • Added image previews
    • Forked from FLSTweak repo
  • 2.0
    • Updated example mod.fls file with measurement label changes, fixed Normal label
  • 1.1
    • Rendered new small font with all characters shifted down 1 pixel
  • 1.0
    • Initial release

Files

  • zeetweak.py - Companion tool for screenshot capture, image/text report generation, arbitrary waveform generation, and buffer dump capture. See below for usage.

  • Zeeweii_DSO3D12 directory:

    • dso3d12_v3.0.7_III_mod_v4.1.fls - an example firmware with all mods applied.
    • images - original and modified UI images.
    • mods - binary patches for use with FLSTweak, including customizable mods (different signal generator waveforms, home screen backgrounds, etc).
  • Ghidra directory:

    • dso3d12_v3.0.7_ghidra_v0.3.gar - reverse engineering project for Ghidra.
      • This is an early stage, with all functions labeled along with embedded data, peripherals and SDK library functions with the SDK data types. Labels and purposes are always up for debate, but it's far enough along to be able to understand how the entire firmware works and spot opportunities for modifications.
      • Usage:
        1. Install the ghidra_csky_WinnerMicro extension - I've forked the original extension to add all C-SKY instructions seen in the Zeeweii firmware for complete disassembly and decompilation.
        2. Open the firmware project in Ghidra using File > Restore Project.
        3. Double-click the firmware image to launch CodeBrowser and view the disassembly and decompiler output.
        4. Feedback appreciated! Feel free to post an Issue or in the EEVBlog forum thread.

Flashing:

wm-tools (Linux/macOS/Windows):

  • A flashing utility by @rssdev10 based on Winner Micro's tool that does not require installing Python or other extras. Note that the Linux and Windows versions are currently untested.

Winner Micro SDK: (Linux/macOS):

  1. Download and extract the WM IoT SDK.
  2. Install required packages - from the wm_iot_sdk directory:
    python -m pip install --user -r tools/wm/requirements.txt
    
  3. With the DSO3D12 turned off, press and hold the power button - the scope will enter a boot loop and enable the scope's serial port to allow for flashing. Keep the power button pressed until flashing is complete.
  4. Check the name of the serial port - on macOS, use the tty.wchusbserial device if two ports are detected:
    % ls /dev/tty*
    /dev/tty.Bluetooth-Incoming-Port
    /dev/tty.usbserial-1410  
    /dev/tty.wchusbserial1410
    
  5. From the wm_iot_sdk/tools/wm/ directory, run flash.py with the serial port and firmware:
    % python3 flash.py --port /dev/tty.wchusbserial1410 --image dso3d12_v3.0.7_III_mod.fls 
    connecting serial...
    serial connected
    trying reset device...
    wait serial sync...
    serial sync success
    trying baudrate 2000000...
    start download image...
    download dso3d12_v3.0.7_III_mod.fls...
    0% [##############################] 100%
    flash device complete
    
  6. Done! Release the power button.

WM Upgrade Tools (Windows):

  1. Download Upgrade Tools.
  2. Change the language to English from the top left menu (third option).
  3. Set "Chip" to W80X and set the image to the firmware .fls file.
  4. Press and hold the scope power button to enable the serial port until flashing is complete.
  5. Select the new COM port, click "Open Serial", and then "Download" to flash.
  6. Done! Release the power button. Flashing_DSO3D12_Upgrade_Tools

zeetweak.py Setup

  1. Install Python.
    • macOS: Installing from python.org or Homebrew can cause conflicts with the Apple-installed version. Consider pyenv or uv.
  2. Install the required packages:
    • macOS/Linux: pip install pyserial numpy matplotlib
    • Windows: py -m pip install pyserial numpy matplotlib
  3. Run the script with the serial port to capture screenshots/buffer dumps, or a file/directory to process existing data:
    • macOS/Linux: python zeetweak.py /dev/tty.usbserial-1410
    • Windows: python zeetweak.py COM1

Screenshots Capture and Rendering

screenshot_viewer_mod is a firmware patch combining two features:

  • Screenshot count repositioning - moves the image count to the upper right of the display, replacing the battery level display.

    • Caveat: This replaces the total screenshot count (displays 1 instead of 1/63). The extra code space has been repurposed for...
  • Screenshot data download - the scope will now automatically transfer the waveform data and scope state/settings via serial when a screenshot is viewed.

    • After capture, zeetweak.py will process and generate:
      1. Waveform image: Uses scope data with matplotlib to build new, high quality screenshots.
      2. Text report: Includes settings/status data and measurements, with extended data when using the --debug option.
      3. CSV file: Structured waveform data for use with other applications.
        • sigrok PulseView - select "Import comma-separated values", select the .csv file, then set "Column format specs" to "t,3a" for 1 channel or "t,6a" for 2 channels.
    • Note: The scope doesn't save the original screenshot as a bitmap image, etc. Instead, it saves the waveform data and settings and regenerates the display as the screenshot.
      • Some data (like channel math) is freshly calculated by the scope when the screenshot is viewed instead of being stored. The script currently doesn't handle this - it's likely more useful to render the data in something like PyQtGraph for fully interactive cursors/math/inversion etc.
    • If you prefer not to have the scope send this data, use the screenshot_viewer_mod_count_reposition_only.bin mod file instead.

Usage

  1. Launch zeetweak.py with the scope's serial port:
    % python zeetweak.py /dev/tty.usbserial-1410  # Windows: COM1, etc
    Waiting for /dev/tty.usbserial-1410... (Ctrl+C to cancel)
    
  2. Power on the scope (it may reset off when the serial port is initialized).
  3. Once the scope is connected, open the screenshot browser and open a saved waveform - the data will be transferred and processed automatically:
    Connected, open saved waveforms to trigger capture:
    Saved data:  Zeeweii_Screenshot_20251225_164225.bin
    Saved CSV:   Zeeweii_Screenshot_20251225_164225.csv
    Saved text:  Zeeweii_Screenshot_20251225_164225.txt
    Saved image: Zeeweii_Screenshot_20251225_164225.png
    

Options

zeetweak.py [-h] [-o OUTPUT] [--color1 COLOR1] [--color2 COLOR2] [--meas MEAS] [--trigline] [--title TITLE] [--datetime] [-w WIDTH] [--debug] source

  • source - Specify the serial port of the scope, a filename (to re-process a previously saved .bin file), or a directory containing multiple saved .bin files to batch process.
  • -o OUTPUT - Specify a filename prefix for the output. If the source is a single file, this will be the entire filename.
  • --color1, --color2 - Specify new channel 1 and channel 2 colors: --color1="yellow" --color2="#ff00ff"
  • --meas - Specify the measurement labels to display in the image (the text output will always show all measurements). By default, the tool will use the measurements displayed in the original screenshot.
    • You can retroactively display all measurements, or select individually:
      • --meas="all"
      • --meas="Freq,PkPk,Avg,RMS,Amp,+Duty,+T,-T,T,Max,Min,Top,Base,-Duty"
  • --trigline - Display a dashed line at the trigger line
  • --nocurs - Disable drawing cursors and measurements
  • --title TITLE - Add a custom title to the image and text report.
  • --datetime - Add the current date and time to custom titles and filenames when processing single files or directories. Timestamp is always added to serial captured files.
  • -w WIDTH - Specify a width in pixels (default: 1650 for 150dpi)
  • --dso2512g_v1 and --dso2512g_v2 - Generate screenshots, CSV, and text reports from DSO2512G scope data files. Requires modified 1.x and 2.x firmware.
  • --debug - Adds extra debugging information during serial capture, including all scope state/settings data in the text report and a diff between sequential images at the console output to help identify additional scope data.

Arbitrary Waveform Patterns

waveform_pattern_mod - most signal generator waveforms are calculated, but the Sinc function (pattern 7) is actually stored as hardcoded data. This makes it possible to replace it with other waveforms that fit in 256 bytes.

  • Quirk: Possibly due to a compiler optimization, the starting sample (1 byte) is hardcoded into the firmware and the remaining 255 bytes are normal data. I've patched the starting sample to be 0x80 (the centerline).
  • zeetweak.py can automatically convert images to waveforms, optionally scale to full dynamic range (0-255), adjust the waveform to align with the hardcoded starting sample, and produce the correctly sized mod data to flash.

To generate a new waveform:

  1. Create a 256x256 image (bmp, png, etc) with a black background and white waveform. The script will resize larger images and pick the bright pixels to use as waveform data.
  2. Run: zeetweak.py --waveform my_waveform.png (add --scale if needed)
  3. Use the output waveform_pattern_mod.bin file with FLSTweak to generate a new flash file.
  4. Flash the firmware and select the Sinc waveform in the signal generator to see your waveform!

A few included examples:

mod_staircase / mod_am:

Waveform-Staircase-AM

mod_ecg / mod_heart:

Waveform-ECG-Heart

Buffer Capture via Secret Dump Mode

Reverse engineering the firmware revealed a function that reads out the FPGA sample buffer (up to 60k samples). This allows capturing higher resolution data that may be usable with other tools to analyze the data. To capture the data:

  1. Launch zeetweak.py with the scope's serial port:
    % python3 zeetweak.py /dev/tty.usbserial-1410
    Waiting for /dev/tty.usbserial-1410... (Ctrl+C to cancel)
    
  2. Power on the scope (it may reset off when the serial port is initialized).
  3. Acquire the signal(s), then press Stop to freeze the sample buffer.
  4. Press Menu, then Stop so that the channel 1 measurements menu is open.
  5. Long-press Save - this kicks off the debug dump:
    Connected, open saved waveforms to trigger capture:
    Receiving data...
    Saved debug dump: Zeeweii_Debug_20251216_180138.bin (270024 bytes)
    Extracted CH1: Zeeweii_Debug_20251216_180138-ch1.bin (60000 samples)
    
    2 channels:
    Receiving data...
    Saved debug dump: Zeeweii_Debug_20251216_145708.bin (285042 bytes)
    Extracted CH1: Zeeweii_Debug_20251216_145708-ch1.bin (30000 samples)
    Extracted CH2: Zeeweii_Debug_20251216_145708-ch2.bin (30000 samples)
    
  6. I recommend also taking a screenshot of the stopped waveform and transferring it - the buffer dump does not include any scope state/settings data (v/div, timebase, etc).

Notes:

  • At full 60k sample depth, it can take up to 20s to transfer the data. At the fastest ranges (5ns, etc), the debug function switches to a fast mode with interpolation and sends 300 samples.
  • The original debug dump converts the data to ASCII and prints it with spaces, line endings, etc. zeetweak.py extracts the data for each channel and saves as normal binary.
  • It should be possible to modify the firmware to directly send hex data and also include the scope state/settings data, on the todo list.

Home Screen Images

The home screen (accessed by pressing the power button once) is simply a full-color image (320x240 16bpp), which opens up the possibility to use any photo or image. I've included a few different options as an example of customizing this UI.

Original -> Mod:

Home

mod_mono / mod_texture:

Home-Mono-Texture

mod_smoke / mod_webb:

Home-Smoke-Webb

Fonts, Images and Labels

  • font_large, font_small - fonts covering ASCII characters 32-126 as 1-bit data.

    • ImageMagick can convert the raw data to a series of images:
      • $ magick -depth 1 -size 8x13 gray:font_small_ref.bin font_small_ref.png
      • $ magick -depth 1 -size 16x16 gray:font_large_ref.bin font_large_ref.png
    • Thanks to @timschuerewegen for developing the fonts (originally for the DSO2512G) and permitting their addition to this repo! Check out the Discord channel for a detailed discussion of Zeeweii firmware and reverse engineering work for the DSO2512G.
  • image_XXXXXX - images are either monochrome 1-bit per pixel or color 16-bits per pixel (RGB565 format); filenames are the offset of the data in the firmware file.

    • 1bpp images:
      • Viewable as PNG files in the images directory
      • Convert raw data to image (must specify the size): $ magick -depth 1 -size 67x198 gray:image_368172_ref.bin image_368172_ref.png
      • Convert image to raw data: $ magick image.png -depth 1 gray:image.bin
    • 16bpp images:
      • Viewable as BMP files in images
    • Thanks to @Dmitur on the EEVBlog forums for locating and documenting these resources, and for permitting their addition to this repo! See the post for additional info.
  • label_calib - fixes typos for DMM calibration text

  • label_measurements - alters the measurements labels and matches the labels in image_364864_mod.bin

  • label_normal - fixes typo for the "Normal" trigger message

Screenshots

Original -> Mod:

Menu-1-Meas

Menu-2-Trig

Menu-3-Disp

Menu-4-Set

Channel-Math

DMM

DMM-Side-Menu

Custom

Resources

About

Reverse-engineered firmware and companion tool for Zeeweii oscilloscopes

Resources

License

Stars

Watchers

Forks

Contributors

Languages