Alright, finally I got some time to fix 3rd harmonics issue. Here you can find instruction and resources to do the same fix for M500.
Couple months ago I got
M500_Firmware_Fix.zip alongside with
Unknown_1.6_Firmware.hex files from SMSL-Mandy, thou he didn't want to send any JTAG\SWD flash tool and I had to investigate the whole process on my own. (Quick note, please do not use
M500右 1v6.hex, because in my case it makes M500 non-bootable).
Inside of the zip file you can find
M500 Update Instructions_EN_.pdf, which says that M500 uses
STM32F103VE chip. I've disassembled the unit and confirmed, that chip is indeed marked as
STM32F103VE, so I've grabbed
STM32F103xE Datasheet and started to look for JTAG\SWD pins. By measuring chip size and number of connection pins I found that M500 uses
LQFP100 14×14 mm STM32F103xE package. Documentation confirms that JTAG/SWD is available for this chip:
Quick document review allows to find
SWDIO and
SWCLK pin names:
SWDIO is
PA13 and SWCLK is
PA14. Here they are:
Directly attaching wires to the chip is a very tricky process and requires some soldering skills, however on the back side of the M500 board (one, which is responsible for the digital processing) we can find JTAG control points, they allow to easily solder wires. Before actual wire solder process I had to ring-out JTAG points to the chip pins, here is screenshot of already connected setup which utilizes Raspberry PI 3:
NOTE: M500 should NOT be powered on by default power cable. Just disconnect everything.
On Raspberry PI GPIO I've used pins #1 for +3.3, #9 for GND, #18 as GPIO 24 for SWDIO and #22 as GPIO 25 for SWCLK, here is diagram:
SPI should be enabled on RaspberryPI. Next we need to install following packages on RPI side:
Bash:
sudo apt-get install git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev
Then clone and build OpenOCD:
Bash:
cd ~
git clone https://github.com/lupyuen/openocd-spi
cd openocd-spi
./bootstrap
./configure --enable-sysfsgpio --enable-bcm2835gpio --enable-cmsis-dap
make
sudo make install
There might be few missing libraries during OpenOCD build process, however it is quite easy to either install them via sudo apt-get install or just by building them from sources. I didn't remember which ones were missing on my RPI, but it took only few mins to resolve all missing libraries, it could be related to the fact, that I'm using DietPI on RPI, which is very lightweight and does not include a lot of software.
Next step is to add correct configuration file for the OpenOCD, here is mine (you need to put it to the /usr/local/share/openocd/scripts/interface/, filename could be raspberrypi3-native.cfg):
Code:
#
# Config for using Raspberry Pi's expansion header
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi's 3.3V and the cable is short enough.
#
# Do not forget the GND connection, pin 6 of the expansion header.
#
interface bcm2835gpio
bcm2835gpio_peripheral_base 0x3F000000
# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 12000MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
bcm2835gpio_speed_coeffs 194938 48
# Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 25 24
bcm2835gpio_swd_nums 25 24
transport select swd
set WORKAREASIZE 0x2000
adapter_khz 4000
source [find target/stm32f1x.cfg]
reset_config none
We need to convert bootloader file from .hex to .bin format, it can be done by installing JLink_V512e.exe from the zip file and running J-Flash tool. File->Open data file->Choose
M500_for_HW1_2.hex or
M500_for_HW1_3.hex (it is
IMPORTANT to choose correct version for your M500, you can find it at M500 system menu, there you will see either HW1.2 or HW1.3). Next File->Save data file as...->and then choose "Binary file (*.bin)" type->provide new file name (for example M500_for_HW1_2.bin) and click Save button.
Copy newly converted bin file to the RPI (for example you can use WinSCP to connect and copy file, or just by placing it on USB stick).
Start OpenOCD with raspberrypi3-native.cfg file (see code above):
Bash:
sudo openocd -f <path to the raspberrypi3-native.cfg>
example:
sudo openocd -f /usr/local/share/openocd/scripts/interface/raspberrypi3-native.cfg
If everything is fine it should start listening on port 4444:
Info : Listening on port 4444 for telnet connections
Now you need to connect to it (please change ip address if you are running telnet from your PC instead of pi):
Now it is time to enter some commands (you can find comprehensive guide at
OpenOCD User’s Guide), but before it we need to confirm flash memory address and length:
So it starts at 0x08000000 and ends at 0x0807FFFF, which is 0x7FFFF total bytes long.
Lets take a current firmware backup first (NOTE: these are the commands, which are running in telnet session):
Bash:
halt
dump_image M500_original_flash_dump.bin 0x8000000 0x7FFFF
resume
I would recommend to save M500_original_flash_dump.bin somewhere else, just in case if new firmware would not work.
Now we can rewrite flash and verify it (you might need to provide full path to the *.bin file, in my case I put them in the same folder where I started openocd):
Code:
halt
flash write_image erase unlock M500_for_HW1_2.bin 0x8000000 bin
resume
halt
verify_image M500_for_HW1_2.bin 0x8000000 bin
resume
Hopefully there should be no errors. It is safe to shutdown RPI and assemble M500 (or you can power it on without case). Here is what I got:
New firmware is 1.7 and date is 2020-5-30, which is the same, as in fixed factory devices. Also DPLL option is available now:
As for the sound quality improvements I would say that both low and top ends are improved: bass goes deeper and highs are a bit more detailed.
I would be glad to answer any questions and guide other members how to fix their devices too.