Voltcraft DSO-3062C

From Random Projects
Jump to: navigation, search
Voltcraft DSO-3062C

The Voltcraft DSO-3062C is an inexpensive (299.- Euros as "special offer" from Conrad) 2-channel digital oscilloscope with 60MHz bandwidth and 1GSa/s samplerate (or 500MSa/s when both channels are used) that can be modified to a 200MHz bandwidth scope via a software change.

It is based on the Samsung S3C2440 (ARM9 SoC) and runs Linux, thus is a very nice "hackable" target in general.


My device

System info

I ordered the device on March 23, 2012 from Conrad, it arrived March 27, 2012. The following versions apply to my unit:

  • Model: DSO3062C
  • SW-Version: 2.06.3(120224.0)
  • HW-Version: 10070x555583e9
  • Serial number: T 1G/012 00xxxx



How to open the device

To be continued...


To be continued...

System information

See Voltcraft DSO-3062C/Sysinfo for the output of various commands run from within the Linux system on the scope (via UART), as well as some vivi bootloader info.

Creating a backup

You can use this tool to create a backup of the oscilloscope firmware.

$ wget 'http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/?action=dlattach;attach=11522' -O fw_backupV3a.zip
$ unzip fw_backupV3a.zip
$ cd Universal
$ mv special_secret_dst1kb_9.99.9_cli\(200101.1\).up 'dst1kb_9.99.9_cli(200101.1).up'

Copy dst1kb_9.99.9_cli(200101.1).up to a USB thumb drive (FAT32 file system), insert the thumb drive in the scope, wait a few seconds, press Utility, press F2 (Firmware upgrade), press F5 (Confirmation that the firmware upgrade should start). Now wait 1-5 minutes, when the process is finished a dialog box tell you to restart the scope.

Afterwards, the USB thumb drive will contain a dump/ directory with boot.bin, kernel.bin, and root.bin files which are dumps of the respective NAND flash partitions.

Upgrading the device to 200MHz bandwidth

USB (Windows)


USB (Linux)

You can use this little Python script (edit it to your needs) as root in order to upgrade the scope from 60MHz to 200MHz.


You'll need to download and install PyUSB >= 1.0 first (the python-usb Debian package does not work, that version is too old and incompatible).

$ unzip pyusb-1.0.0a2.zip
$ cd pyusb-1.0.0a2
$ python setup.py install (as root)

Upgrade script:

IMPORTANT: Use at your own risk! In the worst case your scope could be "bricked"! You have been warned!

#!/usr/bin/env python
# Written by Uwe Hermann <uwe@hermann-uwe.de>, released as public domain.

from array import array
import usb

# Uncomment the line you want to run, or add your own for other variants.
# Filenames: 60MHz = dst1062b, 100MHz = dst1102b, 200MHz = dst1202b
cmd_str = 'mv /dst1062b /dst1202b' # 60MHz -> 200MHz
# cmd_str = 'mv /dst1202b /dst1062b' # 200MHz -> 60MHz

# Find and open the device.
dev = usb.core.find(idVendor = 0x049f, idProduct = 0x505a)
if dev is None:
    print("Voltcraft DSO-3062C not found. Did you connect it via USB?")

# On Linux the 'cdc_subset' driver grabs the device, unload it first.
if dev.is_kernel_driver_active(0):

cmd = [0x43, 0x18, 0x00, 0x11] + map(ord, cmd_str)
checksum = sum(cmd) & 0xff

dev.write(0x01, cmd + [checksum])
# print("Reply: " + str(dev.read(0x82, 64))) # Ignore reply for now.

print("Upon the next boot the scope should be upgraded if nothing went wrong.")


Press CTRL-C to kill dso.exe, press enter to get a shell, then run:

$ mv /dst1062b /dst1202b

Reboot the scope. That's it.



Example captures before and after the 200MHz upgrade

This is a set of example captures done using the Voltcraft DSO-3062C oscilloscope. I used the original PP-80 probes it ships with (60MHz, 10X, 1.2 meters), as well as Tektronix P6139A probes (500MHz, 8.0pF, 10MOhm, 10X, 1.3 meters) for comparison.

50MHz clock signal

This is a set of captures of a 50MHz digital (clock) signal from an FPGA to an SRAM chip.

As a reference, a capture (of the same signal) was done on a Tektronix TDS744A oscilloscope (500MHz bandwidth, 2GSa/s) using the Tektronix P6243 active probe (1GHz, 1MOhm, <1pF, 10X).

100MHz clock signal

This is a set of captures of a 100MHz digital (clock) signal from an FPGA to an SRAM chip.

As a reference, a capture (of the same signal) was done on a Tektronix TDS744A oscilloscope (500MHz bandwidth, 2GSa/s) using the Tektronix P6243 active probe (1GHz, 1MOhm, <1pF, 10X).


Use the J801 header. (TODO: Photos, pinout)

My modular UART cable setup

I'm using a standard FTDI TTL-232R-3V3 cable with some additional custom soldered cables which connect to the three UART pins (RXD0, TXD0, GND) on the PCB. I soldered three individual pins on the PCB for that.

The FTDI cable fits nicely through the space at the back side of the scope which is intended for an Ethernet jack (but not used in this model).


See Voltcraft DSO-3062C/Bootlog for the debug messages output during the boot process.

Login shell via UART

Press CTRL-C to kill dso.exe, then press enter to get a shell.

JTAG (for Samsung S3C2440)


The board has a standard 20pin ARM JTAG connector (just the vias/holes, no pins) onboard. However, it's in 2mm pitch, not the usual 2.54mm pitch most JTAG adapters can attach to per default. You can either solder a 2mm pinheader if you have a proper cable, or build a small converter PCB to 2.54mm pitch, or abuse an old IDE cable (like I did) to solder your own 20pin 2.54mm pitch adapter directly to the PCB. This allows you to attach any standard JTAG adapter easily.

OpenOCD config

The small OpenOCD config I wrote (board/voltcraft_dso-3062c.cfg) has been merged upstream on Apr 2, 2012.

Starting OpenOCD

I'm using a Floss-JTAG adapter here, replace flossjtag-noeeprom.cfg with the config file for your adapter.

$ openocd -f interface/flossjtag-noeeprom.cfg -f board/voltcraft_dso-3062c.cfg
Open On-Chip Debugger 0.6.0-dev-00493-gd40cb56 (2012-04-01-02:14)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect 'jtag'
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
12000 kHz
Info : max TCK change to: 30000 kHz
Info : clock speed 10000 kHz
Info : JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (mfg: 0x04e, part: 0x0324, ver: 0x0)
Info : Embedded ICE version 2
Info : s3c2440.cpu: hardware has 2 breakpoint/watchpoint units
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x200000d3 pc: 0x00000480
MMU: disabled, D-Cache: disabled, I-Cache: disabled

Using OpenOCD

In another xterm run:

$ telnet 4444

You can now dispatch any OpenOCD commands you want, for example:

> targets
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* s3c2440.cpu        arm920t    little s3c2440.cpu        halted

> scan_chain
   TapName             Enabled  IdCode     Expected   IrLen IrCap IrMask
-- ------------------- -------- ---------- ---------- ----- ----- ------
 0 s3c2440.cpu            Y     0x0032409d 0x0032409d     4 0x01  0x0f

> nand probe 0
NAND flash device 'NAND 64MiB 3.3V 8-bit (unknown)' found

> nand list
#0: NAND 64MiB 3.3V 8-bit (unknown) pagesize: 512, buswidth: 8,
        blocksize: 16384, blocks: 4096

Dumping the NAND flash

You can dump the full NAND flash contents to a file using JTAG, however this seems to take many hours. It probably depends a lot on the JTAG adapter used, and maybe there's something wrong in my setup which causes the slowness, this will be investigated later.

> init_2440
> nand dump 0 voltcraft_dso-3062c_nand_dump_normal.dd 0 0x4000000
Info : s3c2440_read_block_data: reading data: 0xfae650, 0xfeae80, 512
Info : s3c2440_read_block_data: reading data: 0xfae650, 0xfeae80, 512
dumped 67108864 bytes in 35135.664062s (1.865 KiB/s)

You can also dump the full NAND flash chip contents including the OOB data:

> init_2440
> nand dump 0 voltcraft_dso-3062c_nand_dump_oob_raw.dd 0 0x4000000 oob_raw
dumped 69206016 bytes in 36184.039062s (1.868 KiB/s)






Building buildroot and an arm-linux cross toolchain

First install some requirements, in case you don't have them already:

$ apt-get install build-essential bison flex gettext libncurses-dev git-core subversion

Then get the buildroot source code from the git repo:

$ cd $HOME
$ git clone git://git.buildroot.net/buildroot buildroot-git-eabi
$ cd buildroot-git-eabi

Configure buildroot, select the target architecture, toolchain, and packages you want to build:

$ make menuconfig

I used the following settings (some are required, others are optional, depends a lot on your needs):

  • Target Architecture: ARM (little endian)
  • Target Architecture Variant: arm920t
  • Target ABI: EABI
  • Toolchain:
    • Toolchain type: Buildroot toolchain
    • Kernel Headers: Linux 3.3.x kernel headers (the version here must match the kernel version you'll use on the board, otherwise stuff could break)
    • GCC compiler Version: gcc 4.6.x (default is gcc 4.5.x, but the newer 4.6.x version works fine too)
    • Purge unwanted locales (leave only "C en_US" selected, this saves a lot of space)
    • Enable large file (files > 2 GB) support (needed for some packages)
    • Enable IPv6 support (needed for some packages)
    • Enable WCHAR support (needed for some packages)
    • Enable C++ support
  • Package selection:
    • BusyBox (already selected, this is the bare minimum you need)
    • Graphic libraries and applications (graphic/text) / Libraries:
      • directfb, SDL, Qt, cairo, gdk-pixbuf, gtk2, others (if you want to write graphical programs)
    • Hardware handling:
      • mtd/jffs2 utilities (useful for NAND utilities in the Linux system later)
      • u-boot tools (for fw_printenv)
    • Networking applications:
      • lrzsz (I'm using the zx tool from this package to transfer files to the target via serial console + minicom; you can also use other means though)
  • Filesystem images:
    • jffs2 root filesystem
      • Flash Type: NAND flash with 512B Page and 16 kB erasesize
      • Pad output (otherwise the respective nand write command in U-Boot will fail later on)
      • Produce a summarized JFFS2 image (apparently this speeds up boot time a bit, if your kernel supports "summarized" JFFS2 images, which it will).
    • You can un-select tar the root filesystem, it's not needed if you just write JFFS2 images to NAND flash.
  • Do not select anything in "Bootloaders" or "Kernel", we'll build those independently later.

Save the settings and exit menuconfig, then build all the stuff:

$ make

The resulting rootfs.jffs2 file is what you can write to NAND flash later; it's located in the output/images directory.

The arm-linux toolchain which was built, is located in output/host/usr/bin etc.

Linux kernel

Building a Linux kernel

Download and extract the latest release of the mainline Linux kernel:

$ wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.3.1.tar.bz2
$ tar xfvj linux-3.3.1.tar.bz2
$ cd linux-3.3.1

Configure the kernel:

$ make ARCH=arm menuconfig

TODO: Describe config options to use.

Build the kernel:

$ export PATH=$PATH:$HOME/buildroot-git-eabi/output/host/usr/bin
$ make ARCH=arm CROSS_COMPILE=arm-linux- uImage
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-3.3.1
Created:      Thu Apr  5 00:31:52 2012
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    2366848 Bytes = 2311.38 kB = 2.26 MB
Load Address: 30008000
Entry Point:  30008000
  Image arch/arm/boot/uImage is ready

You'll get an arch/arm/boot/uImage file (for use with the U-Boot bootloader) and also the "traditional" arch/arm/boot/zImage' file (e.g. for use with the vivi bootloader).

vivi bootloader

System info

See Voltcraft_DSO-3062C/Sysinfo#vivi_bootloader.

Loading a Linux kernel into SDRAM via XMODEM

Tekway> load ram 0x30008000 2366848 x

Then, in minicom on the host, press CTRL-a z, then press s, select xmodem, and select the file you want to transfer (a zImage in this case). In this example 0x30008000 is the (RAM) location where the file should be stored and 2366848 is the size of the file.

If this doesn't work, you probably have to increase the value for the xmodem_initial_timeout parameter in the vivi bootloader beforehand:

Tekway> param set xmodem_initial_timeout 100000000

Executing a Linux kernel from RAM

Tekway> go 0x30008000
go to 0x30008000
  argument 0 = 0x00000000
  argument 1 = 0x00000000
  argument 2 = 0x00000000
  argument 3 = 0x00000000
Uncompressing Linux... done, booting the kernel.


Building U-Boot



Building Barebox

Note: This is work in progress!

Add the bin directory (where the toolchain you built above resides) to your $PATH:

$ export PATH=$PATH:~/buildroot-git/output/host/usr/bin

Get the Barebox source code via git:

$ git clone git://git.pengutronix.de/git/barebox.git
$ cd barebox

Configure Barebox:

$ make ARCH=arm menuconfig

You have to select a few important options, the other ones are optional and you can configure them as you see fit.

  • ARM system type (Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443)
  • S3C24xx Board Type (Mini 2440) (for now)
  • ...

Build Barebox:

$ make ARCH=arm CROSS_COMPILE=arm-linux-
LD      barebox
SYSMAP  System.map
OBJCOPY barebox.bin
CHKSIZE barebox.bin

Running Barebox from RAM

In OpenOCD run:

> init_2440
> load_image barebox.bin 0x31fc0000
95984 bytes written at address 0x31fc0000
downloaded 95984 bytes in 3.942175s (23.777 KiB/s)
> resume 0x31fc0000

On UART you will see something like this (for now):

barebox 2012.03.0-00113-g96a43ca (Apr  1 2012 - 23:34:21)

Board: Mini 2440
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)
Bad block table not found for chip 0
Bad block table not found for chip 0
Scanning device for bad blocks
Bad block table written to 0x03ffc000, version 0x01
Bad block table written to 0x03ff8000, version 0x01
refclk:    12000 kHz
mpll:     405000 kHz
upll:      48000 kHz
fclk:     405000 kHz
hclk:     101250 kHz
pclk:      50625 kHz
SDRAM1:   CL4@101MHz
SDRAM2:   CL4@101MHz
Malloc space: 0x31bc0000 -> 0x31fbffff (size  4 MB)
Stack space : 0x31bb8000 -> 0x31bc0000 (size 32 kB)
envfs: wrong magic on /dev/env0
no valid environment found on /dev/env0. Using default environment
running /env/bin/init...
not found

Dumping the NAND flash contents using Barebox

$ memcpy -s /dev/nand0 -d /dev/mem 0x0 0x30000000 0x4000000
err -74
read: error 74

NOTE: This doesn't seem to work, yet. It works if you try to dump smaller chunks though (e.g. 2MByte). Using -b, -w, or -l doesn't help. Using nand -a /dev/nand0 and then dumping the generated /dev/nand0.bb doesn't work either. The NAND chip seem to be detected correctly though, and you can also view parts of its contents via md, like this:

barebox:/ md -s /dev/nand0 0xe190
0000e190: 33f00de8 00000000 33f13188 69766976                ...3.....1.3vivi
0000e1a0: 00000000 00000000 00000000 00000000                ................
0000e1b0: 00020000 00000000 6f6f6265 00000074                ........eboot...
0000e1c0: 00000000 00000000 00020000 00020000                ................
0000e1d0: 00000000 61726170 0000006d 00000000                ....param.......
0000e1e0: 00000000 00040000 00010000 00000000                ................
0000e1f0: 6e72656b 00006c65 00000000 00000000                kernel..........
0000e200: 00050000 00200000 00000000 746f6f72                ...... .....root
0000e210: 00000000 00000000 00000000 00250000                ..............%.
0000e220: 03dac000 00000000 00000005 6863616d                ............mach
0000e230: 7079745f 00000065 00000000 00000000                _type...........
0000e240: 00000000 0000030e 00000000 6964656d                ............medi
0000e250: 79745f61 00006570 00000000 00000000                a_type..........
0000e260: 00000000 00000003 00000000 746f6f62                ............boot
0000e270: 6d656d5f 7361625f 00000065 00000000                _mem_base.......
0000e280: 00000000 30000000 00000000 64756162                .......0....baud

Loading a Linux kernel into RAM using YMODEM

barebox:/ loady -c -b 115200
## Ready for binary (ymodem) download to 0x00000000 offset on image.bin device
## Total Size      = 0x00241dc0 = 2366912 Bytes

Then, in minicom on the host, press CTRL-a z, then press s, select ymodem, and select the file you want to transfer (a uImage in this case). The file will be available as /image.bin in the Barebox "filesystem".

Note: The loady command is not enabled per default in Barebox at the moment.

Show info about the uImage we just loaded:

barebox:/ uimage -i image.bin
Image at image.bin:
  Image Name:   Linux-3.3.1
  Created:      2012-04-05  10:45:12 UTC
  OS:           Linux
  Architecture: ARM
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    2366848 Bytes =  2.3 MB
  Load Address: 30008000
  Entry Point:  30008000

Verify the uImage:

barebox:/ uimage -v image.bin
verifying data crc... ok

Starting the kernel:

barebox:/ bootm -c -v image.bin
  Image Name:   Linux-3.3.1
  Created:      2012-04-05  10:45:12 UTC
  OS:           Linux
  Architecture: ARM
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    2366848 Bytes =  2.3 MB
  Load Address: 30008000
  Entry Point:  30008000

Loading OS U-Boot uImage 'image.bin'
OS image is at 0x30008000-0x30249d7f
Passing control to ARM Linux uImage handler

Starting kernel at 0x30008000...
commandline: <NULL>
arch_number: 1999
Uncompressing Linux... done, booting the kernel.


Personal tools