Hacking the DPS5005

Some time ago I found the DPS5005 while browsing AliExpress for programmable power supplies. To be honest, I dismissed the ‘5005 since it was not a complete product. Then HAD wrote about it in december last year and after watching YouTube user @iforce2d’s video I just had to get one. The overall impression was quite good but the software was a bit cluttered and the DPS5005 could not be instrumented via a serial port (or wifi). Looking closely at the sandwich PCB design I noticed the DPS is powered by an STM32, which is pretty much what I expected. And so begun the OpenDPS project, a free firmware replacement for the DPS5005 and friends.

OpenDPS, wifi connected
OpenDPS, wifi connected

This write up of the OpenDPS project is divided into three parts. Part one (this one) covers reverse engineering the stock firmware and could be of interest for those looking at reverse engineering STM32 devices in general. Part two covers the design of OpenDPS, the name given to the open DPS5005 firmware. Part three covers the upgrade process of stock DPS:es and connecting these to the world. If you only want to upgrade your DPS you may skip directly to part three.

Reverse engineering the DPS5005

The reverse engineering of the DPS5005 can be summarised as “bring up of the STM32 based DPS5005 hardware and writing an application for it”. This is pretty much my day job but I always have the hardware schematics and the hardware design engineer at hand. This time, obviously, I had neither which was a bit more challenging. So where does one start? Looking at the PCB, I quickly found the serial port. That was a dud, completely silent. Fake port! I later realised the DPS5005 stock firmware does not even initialise the serial port. The STM32 is covered by the TFT display, which in turn is soldered using eight pins. As I did not have the time to play with iron and solder wick I resorted to a metal saw and promptly sawed the TFT display off (please note this is not the unit in the pictures below).

SWO pinout
Top: SWO pinout, UART below

Warranty voided, oh there actually was none to begin with. Having the STM32 in the open quickly allowed me to identify the five test points at the top of the PCB, the expected SWO trace port. But had the producers locked the SWO port when flashing the firmware? Luckily, no.

Debugger connected
Debugger connected

After some soldering, connecting an STLink clone and selecting an appropriate OpenOCD configuration for the STM32F100, I had a go at it:

Yay! Next I connected to OpenOCD to examine the target:

So “readout protection” is enabled which mean you cannot read the firmware from flash. Not a biggie as I was not interested in the stock firmware in itself, only what it controlled. So what would be needed to create the OpenDPS firmware?

  • Learn how buttons and other IOs are connected.
  • What STM32 peripheral drives what function?
  • Controlling the output voltage (controlled by the DAC?)
  • Current limiter (maybe ADC?)
  • Measuring input and output voltage (definitely ADC)
  • Dimmable TFT (not needed 🙂
  • Write a TFT driver

To assist, I created a Python script (ocd-client.py) connecting to OpenOCD for dumping various STM32 device registers. Eg, by dumping the entire DAC register area I could determine the DAC was in use. The buttons I could identify by dumping the GPIO input registers, pressing the button and dumping the registers again. The entire GPIO setup can be recreated by this script and I learned the output voltage really is driven by the DAC. The TFT backlight is driven by timer 4 and the output current, input voltage and output voltage are measured using ADC1 on channels 7, 8 and 9. The 1.44″ TFT is an ILI9163C and I used @SumoToy’s driver for this. The SPI select pin for the display is grounded which is a clever way of saving one pin for designs where there is only one device connected on the SPI bus. Additionally, the display does not use the MISO pin. The most important thing now was how to control the DAC to set a desired output voltage, how to interpret the ADC1 values measuring the output voltage, current draw and input voltage. Normally, one would look at the schematics to figure out what an ADC reading means but in this case I had to reverse engineer that. I simply connected a multimeter, tried a few settings on the stock firmware, observed the ADC1 reading and plotted the result. Next, I created a simple application using the lovely libopencm3 and tested in on a “Bluepill” before wiping the DPS5005. Telnetting to port 4444 again I tried:

Failed! Hmmm, let’s do a power cycle, restart OpenOCD and try that again.

Now that’s better! I am not sure why it fails the first time, it did so on both my units but succeeded on the second attempt. A simple ‘make flash’ and the display showed my test pattern and the power output was at the expected 5V. Mission, partly, accomplished! I could reflash the DPS5005 and control the voltage setting. Time to write a proper application. More in part two.

11 thoughts on “Hacking the DPS5005

  1. Pingback: Open Source Firmware for DPS5005 Power Supply - Hacked Gadgets – DIY Tech Blog

    1. Ian Oliver

      I’m also interested in this as I have a DP30V5A. I love the module but the user interface is deeply odd and I keep pressing the wrong button. Setting a preset is particularly difficult and I have to refer to my crib sheet every time.

  2. Pingback: Open Source Firmware For A Cheap Programmable Power Supply | Hackaday

  3. Thanh Tran

    Awesome work! Thanks for the great write up
    I’ve been looking around to see if anyone has open source firmware for this device and finally found your post.
    I use a lipo pack to power this little DPS gadget. I wanted it to be able to turn off itself when the input voltage is lower than a set threshold or if the mAh has passed some set numbers. I’ve not looked at your codes, but I think it should be easy to add this feature.

  4. Pingback: 0. Что не так с DPS5005? | zhevak

Leave a Comment

Your email address will not be published. Required fields are marked *

*
*