DPS5005: Difference between revisions

From Leo's Notes
This page was last edited on 9 June 2021, at 05:42.
mNo edit summary
Linked to OpenDPS
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
The DPS5005, and related DPS3005, DPS5015, DP50V5A, are smart buck regulators and can be used as a budget 'bench' power supply modules. These units are powered by a STM32F100 microprocessor and includes a 1.44" TFT color LCD display.
The DPS5005, and related DPS3005, DPS5015, DP50V5A, are smart buck regulators and can be used as a budget 'bench' power supply modules. These units are powered by a STM32F100 microprocessor and includes a 1.44" TFT color LCD display.


The more recent versions of DP50V5A and the DPS5005 are virtually identical except for the difference in firmware. The DP50V5A has an inferior firmware which makes the interface laggy along with a slight difference in how the M1/M2 buttons are mapped. Despite these differences, OpenDPS can be installed and the button mappings can be made to work in the same manner.
The more recent versions of DP50V5A and the DPS5005 are virtually identical except for the difference in firmware. The DP50V5A has an inferior firmware which makes the interface laggy along with a slight difference in how the M1/M2 buttons are mapped. Despite these differences, [[OpenDPS]] can be installed and the button mappings can be made to work in the same manner.


==OpenDPS==
== Custom firmware ==
The stock firmware can be overwritten with an open source firmware called OpenDPS. The official project repo is at https://github.com/kanflo/opendps.  
You can load a customized open source firmware called [[OpenDPS]]. All you need is a STLink and some fine wire to connect to the JTAG on the back of the unit and a computer that can run OpenOCD.


I have added additional features to OpenDPS including the colorful DPS-like display from the original firmware and can be found on my private repo under the <code>dps_mode</code> branch at https://git.steamr.com/others/opendps/-/tree/dps_mode/opendps
==STM32 flash information==
 
Some additional features that OpenDPS has include:
 
*Serial/Wi-Fi control
*A function generator (limited by hardware specs)
*A countdown timer
*A watt-hour meter (useful for checking how much power a battery took to charge)
 
===Compiling and installing===
 
====Software requirements====
You will need the following to get OpenDPS running on your power supply:
 
*A STLink or STLink clone
*A computer with OpenOCD, ARM cross compiler (<code>gcc-arm-none-eabi</code>), make, and git
 
You may use the following Dockerfile to set up the build environment or follow the RUN step below to install the necessary dependencies.
 
{{Highlight
| code = FROM ubuntu:20.04
 
ARG ARM_TOOLCHAIN_URL="https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2"
 
RUN set -ex; \
        apt-get update; \
        apt-get install -y wget; \
        wget -O /tmp/gcc-arm-none-eabi.tar.bz2 "$ARM_TOOLCHAIN_URL"; \
        mkdir /opt/gcc-arm-none-eabi; \
        tar -xjvf /tmp/gcc-arm-none-eabi.tar.bz2 -C /opt/gcc-arm-none-eabi --strip-components 1; \
        rm /tmp/gcc-arm-none-eabi.tar.bz2; \
        rm -rf /var/lib/apt/lists/*
 
# add the tools to the path
ENV PATH="/opt/gcc-arm-none-eabi/bin:${PATH}"
 
RUN set -ex; \
        apt-get update; \
        apt-get install -y git openocd make python netcat
| lang = text
}}
 
Create the Docker image by placing the contents above into a <code>Dockerfile</code>, then build the image by <code>running docker build -t gcc-arm-none-eabi .</code>.
 
Run the image with access to your USB bus so that <code>openocd</code> can talk to your STLink by running:
 
{{Highlight
| code = $ docker run --rm -ti --privileged -v /dev/bus/usb:/dev/bus/usb -v `pwd`:/data gcc-arm-none-eabi bash
| lang = terminal
}}
 
====Hardware====
[[File:STLink DPS Pinout.jpg|thumb|right|300px]]To begin, connect your STLink to the DPS as per the pinout in the picture on the right.  Connect the STLink to your computer and then apply power to the DPS power supply. OpenOCD should be able to detect the device.
{{highlight|lang=terminal|code=
pi@raspberrypi:~/opendps$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.236988
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'telnet' connection on tcp/4444
}}
 
In case your device is unique and has no support, use the bundled {{code|ocd-client.py}} script to generate a log file with all registers, hardware peripherals including ADC and DACs, timers, GPIOs, etc. If you are working on a supported device (that is, the {{code|dps-models.h}} file has mention of your model), you should be safe to skip this step.
 
If your device isn't listed in the <code>dps-models.h</code> header file, it's recommended that you create a few dumps of the device in different states (Off / On and set to different voltages) in order to make it easier to identify which GPIO pins and ADC/DACs are in use and for what purpose. The stock firmware may freeze when OpenOCD is used. The only work-around is to configure the device with the STLink disconnected and the re-connect the STLink when you are ready to create a dump. Dumps are created with {{code|ocd-client.py}} script like this:{{highlight|lang=terminal|code=
$ python ocd-client.py all > dump.txt
}}
 
====Compiling====
To compile and flash OpenDPS on your device, clone the OpenDPS repository. I will be using my <code>dps_mode</code> branch in the examples below, but you may substitute it with the official OpenDPS repository.
{{highlight|lang=terminal|code=
$ git clone --branch dps_mode https://github.com/kohrar/opendps.git
}}
 
On the project root directory, compile OpenDPS:
{{highlight|lang=terminal|code=
## Compile OpenDPS and then flash it on the device:
$ make -C opendps flash -j 9 MODEL=DPS5005 INVERT_ENABLE=0 CC_ENABLE=0 CL_ENABLE=0 CV_ENABLE=0 POWER_COLORED=1 POWER_OFF_VISIBLE=1 THERMAL_LOCKOUT=0  FUNCGEN_ENABLE=0 SETTINGS_ENABLE=1 DPSMODE_ENABLE=1 WDOG=1
 
## Flash the boot loader:
$ make -C dpsboot flash
}}
 
Adjust the make flags as desired. I leave most features disabled as I prefer to only have the DPS screen and settings screen without the features.
 
=====Troubleshooting compile issues=====
If you get an error similar to: <code>opendps/libopencm3/include/libopencm3/dispatch/nvic.h:8:11: fatal error: libopencm3/stm32/f1/nvic.h: No such file or directory</code>, try running make without any arguments. This should pull in and build the libopencm3 dependency. This issue seems to be an issue with the Makefile on a clean build directory.
 
If your firmware doesn't appear to have the appropriate features as defined by the make flags, you may need to clear out all the objects and compiled binaries before building again. Just run: <code>rm opendps/*.o /data/opendps/opendps/opendps_DPS5005.*</code>  .
 
===Usage guide===
OpenDPS is organized by separating features into different screens. By default, the firmware will start in the DPS mode screen displaying the preset voltage, current, and power. When using OpenDPS, keep in mind the following key combinations:
{| class="wikitable"
!Key Combination
!Description
|-
|On/Off button
|Turns on / off power
|-
|hold M1 and M2
|Calibration screen
|-
|SET + turn rotary
|Change screens left or right
|-
|Hold M1 or hold M2
|In DPS mode, this will recall M1 or M2
|-
|SET + M1 or SET + M2
|In DPS mode, this will set M1 or M2 to your current voltage/current values
|-
|Hold down rotary
|Locks or unlocks the UI from unintended changes
|}
 
====DPS Mode Screen====
The DPS Mode screen shows the voltage, current, and power output being supplied by the power supply and was designed to look and feel as close to the original DPS firmware as possible while retaining a cleaner user interface. Until this feature is merged in the official repo, you can get it by merging the pull request or use the [https://git.steamr.com/others/opendps/-/tree/d4 d4 branch on my repo]. This feature is enabled by default using the <code>DPSMODE_ENABLE</code> flag. When building from this branch, the options I used were: <code>make -C opendps flash -j 9 MODEL=DPS5005 INVERT_ENABLE=0 CC_ENABLE=0 CL_ENABLE=0 CV_ENABLE=0 POWER_COLORED=1 POWER_OFF_VISIBLE=1 THERMAL_LOCKOUT=0 SETTINGS_ENABLE=1</code>
 
[[File:DSP5005 Interface.png|frame|center|DSP5005 Interface]] Buttons work as you would expect: {{code|V}} will allow editing of the maximum voltage. {{code|A}} will allow editing of the maximum current.
 
The user interface can be locked by holding the {{code|Rotary}} down until a padlock symbol appears near the bottom of the screen.  Conversely, the interface can be unlocked by holding the {{code|Rotary}} down until the padlock symbol disappears.
 
-----
 
[[File:DSP5005 Third Item Interface.png|center|frame|DSP5005 Third Item Interface]] The third value on the screen can be changed using the {{code|Rotary Press}} + {{code|Rotary Turn}} combination. Values that are displayed in the third row can be edited using {{code|Rotary Press}}, or by navigating through the interface using {{code|SET}} + {{code|M1}} or {{code|SET}} + {{code|M2}}. The DPS Mode screen currently supports editing of:
 
*Power Output / Power Limit
*Timer (time until power off, or time since power on)
*Brightness
*Watt-Hour Meter (measured in milliwatt-hours).
 
------
 
[[File:DSP5005 Power Interface.png|center|frame]] When the DPS unit is turned on, you will see either {{code|CC}} or {{code|CV}} signifying whether the device is in constant current or constant voltage mode. Depending on the power output limit that is set, a power output warning may be seen when power output exceeds 80% of the power limit. Exceeding the power limit will automatically turn the output off.
------
 
[[File:DSP5005 Preset and Timer.png|center|frame]] The DPS screen supports up to two recall preset  settings. Each preset setting saves the voltage, current limit, power limit, and timer value. Recall a preset by holding {{code|M1}} or {{code|M2}}. Save a preset by holding {{code|SET}} + {{code|M1}} or {{code|SET}} + {{code|M2}}.
 
If a timer is set prior to power on, a hourglass icon will flash signifying that a timer is set. When the timer elapses, power will automatically be shut off. If the timer is not set prior to power on, the timer will act as a clock and will show the duration since power on.
 
===Calibration===
Voltage and current are controlled using a pair of DAC and ADCs. The two DACs control the output current and voltage while the two ADCs measure the current and voltage. Typically, you will need to calibrate these DACs and DACs in order to have accurate values.
 
Calibration involves finding the slope (K) and offset constant (C) of the DAC/ADC curve. The curve is linear and can be found by finding two points. For DACs, we want to map the input value to the DAC (0 ~ 4096) to the actual output value (voltage or current limits). For ADCs, we want to map the ADC output (0 ~ 4096) to its actual value (voltage or current).
 
Default values are defined in  {{code|dps-model.h}} but can be changed on the fly in the settings screen. To help calculating the appropriate K and C values, use the spreadsheet to calculate the DAC and ADC values.
 
====DAC====
The DAC is the simplest to calibrate. Hit M1 and M2 buttons simultaneously to enter the calibration menu. From this menu, you can set the input DAC values for both voltage and current DACs. Alternatively, you can set the voltage DAC value by writing to register DHR12R1 at address 0x40007408 and the current DAC by writing to register DHR12R2 at address 0x40007414.
 
We will map this voltage value to the actual voltage that is measured with a reference multimeter.
 
For voltage:
 
#Hit M1+M2 to enter calibration menu
#Assign {{code|Vout DAC}} a value of 50 (this is D1)
#Measure the voltage with a reference multimeter (V1)
#Assign {{code|Vout DAC}} a value of 500 (this is D2)
#Measure the voltage again. (V2).
#Calculate the K value: (D1 - D2) / (V1 - V2)
#Calculate the C value: D1 - (K * V1)
#Update values for K and C as V_DAC_K and V_DAC_C.
 
The same principle applies for the current DAC but with slightly different values.
 
#Hit M1+M2 to enter calibration menu
#Assign {{code|Iout DAC}} a value of 500 (this is D1)
#Connect a current sink (ideally 2+ amps). Measure the current as C1
#Assign {{code|Iout DAC}} a value of 1200 (this is D2)
#Measure the current as C2
#Calculate the K value: (D1 - D2) / (C1 - C2)
#Calculate the C value: D1 - (K * C1)
#Update values for K and C as A_DAC_K and A_DAC_C.
 
 
====ADC====
The ADC K/C values can be calibrated by calculating the original raw value based on the measured and actual voltage/current and then adjusting the existing K/C values to account for any drift. Use the spreadsheet to help with this calculation.
 
#Plug in the existing K and C values to the spreadsheet
#First column takes a lower value.
##Turn the power on so that the DPS is supplying power
##Enter the a voltage reading as displayed
##Enter the actual voltage by measuring the DPS voltage output
#Repeat for the higher-end value
#Enter the new K and C values
 
These steps apply to current as well.
 
===Development===
[[File:DPSmode-Display.jpg|thumb|right|DPS Mode on OpenDPS running on a DP50V5A]]
OpenDPS is open source and is very easy to add new features.
 
====Fonts====
The Makefile is capable of rendering different fonts to be used in the firmware. Copy your <code>.ttf</code> or <code>.otf</code> font to the {{code|gfx}} directory and edit the {{code|Makefile}}. Alternatively, override the <code>Makefile</code> values and then run:
{{highlight|lang=terminal|code=
# make -C opendps fonts
# make -C opendps fonts METER_FONT_FILE=`pwd`/nf.ttf METER_FONT_SMALL_SIZE=16 METER_FONT_MEDIUM_SIZE=22 METER_FONT_LARGE_SIZE=30
}}
 
====Graphics====
Convert a <code>.png</code> with the script:
{{highlight|lang=terminal|code=
% python gen_lookup.py -i gfx/png/poweroff.png -o poweroff
Converting gfx/png/poweroff.png to gfx-poweroff.c/h
}}You may need to run this inside a container as the script depends on python2 and Pillow. On a Fedora 28 docker image, run:
{{Highlight
| code = # yum install redhat-rpm-config zlib-devel zlib gcc python-devel @development-tools
# pip install Pillow==2.2.1
| lang = terminal
}}
Additionally, you may encounter an error with PIL resulting in "<code>SystemError: unknown raw mode</code>". This requires the following change to work:
{{Highlight
| code = -    image_bytes = im.tobytes("raw", "RGB") # Create a byte array in 24 bit RGB format from an image
+    image_bytes = im.convert("RGBA").tobytes("raw", "RGB") # Create a byte array in 24 bit RGB format from an image
| lang = diff
}}
 
==STM32 Flash Information==
The STM32F100 has a 64KB/(128KB?) flash. The original firmware is protected and cannot be read. You can disable readout protection by unlocking the STM32 microcontroller but this will wipe all existing data.
The STM32F100 has a 64KB/(128KB?) flash. The original firmware is protected and cannot be read. You can disable readout protection by unlocking the STM32 microcontroller but this will wipe all existing data.



Latest revision as of 05:42, 9 June 2021

DPS50V5A and a DPS3005

The DPS5005, and related DPS3005, DPS5015, DP50V5A, are smart buck regulators and can be used as a budget 'bench' power supply modules. These units are powered by a STM32F100 microprocessor and includes a 1.44" TFT color LCD display.

The more recent versions of DP50V5A and the DPS5005 are virtually identical except for the difference in firmware. The DP50V5A has an inferior firmware which makes the interface laggy along with a slight difference in how the M1/M2 buttons are mapped. Despite these differences, OpenDPS can be installed and the button mappings can be made to work in the same manner.

Custom firmware

You can load a customized open source firmware called OpenDPS. All you need is a STLink and some fine wire to connect to the JTAG on the back of the unit and a computer that can run OpenOCD.

STM32 flash information

The STM32F100 has a 64KB/(128KB?) flash. The original firmware is protected and cannot be read. You can disable readout protection by unlocking the STM32 microcontroller but this will wipe all existing data.

$ telnet localhost 4444
> flash list
{name stm32f1x base 134217728 size 131072 bus_width 0 chip_width 0}
> flash banks
#0 : stm32f1x.flash (stm32f1x) at 0x08000000, size 0x00020000, buswidth 0, chipwidth 0

> halt
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x61000003 pc: 0x080001d2 msp: 0x200007a8

> stm32f1x options_read 0
Option Byte: 0x3fffffe
Readout Protection On
Software Watchdog
Stop: No reset generated
Standby: No reset generated
User Option0: 0xff
User Option1: 0xff

Readout Protection is set to On, which can be changed by changing the Read Protection (RDP) level. There are 3 levels:

  • 0: No read protection.
  • 1: Read protection enabled.
  • 2: Debug/chip read protection disabled. Will disable JTAG, which is bad for our case.

By changing the RDP value from 1 to 0, you will erase the flash.

> stm32f1x unlock 0
Device Security Bit Set
target halted due to breakpoint, current mode: Handler HardFault
xPSR: 0x61000003 pc: 0x2000003a msp: 0x2000076c
stm32x unlocked.
INFO: a reset or power cycle is required for the new settings to take effect.

> stm32f1x options_read 0
Option Byte: 0x3fffffc
Readout Protection Off
Software Watchdog
Stop: No reset generated
Standby: No reset generated
User Option0: 0xff
User Option1: 0xff

Notes

On a DPS5005, these are the values I see:

> flash list
{name stm32f1x base 134217728 size 0 bus_width 0 chip_width 0}{name stm32f1x base 134217728 size 0 bus_width 0 chip_width 0}
> stm32f1x options_read 0
device id = 0x10016420
STM32 flash size failed, probe inaccurate - assuming 128k flash
flash size = 128kbytes
Option Byte: 0x3fffffe
Readout Protection On
Software Watchdog
Stop: No reset generated
Standby: No reset generated
User Option0: 0xff
User Option1: 0xff

See Also