It's a few years already I started to dig in the QSPI flash of the PSS-A50 (and a bit in the PSS-F30 one). I desoldered the flash chip in order to extract the data with a QSPI reader.
Then I started at first to identify the data blocks in order to understand how the samples are built and accessed depending on the selected voice and key pressed. Visually by watching some repetitive patterns in an hex editor (HxD).
Thanks to Ghidra I could go deeper in the firmware, and confirm the YMW830 SWLL was based on Armv7 big endian. Then try to identify the GPIO ports and try to locate the registers of the audio core in the SOC. Not all the firmware is run XIP from the Flash (Executed In Place, means runs directly from the QSPI Flash -with a small buffering-). I could notice that part of the SW was copied from Flash to RAM, and ran from RAM. But I had to admit that some subroutines were called in the (supposed) internal ROM of the YMW830 SWLL.
I could get a better understanding using a (very) high speed logic analyzer connected directly on the QSPI in order to get a "real time" dump of the µC access, while the PSS-A50 is running (needed to be decoded later). Which could help to understand the boot process. It boots at first in SPI mode, copy some code to RAM, and then switches to QSPI mode start the execution of the rest of the firmware.
My assumption was that "they" probably blown the jtag fuses in order to lock the access to the internal ROM... so I did not spend any time trying to connect a JTAG probe (that I don't have btw).
But a few days ago, I discovered here that the JTAG access was enabled : https://mastodon.social/@whitequark/113694931960849696
Catherine/@whitequark could connect to the JTAG using her own "glasgow" HW (kind of "Bus Pirate") : https://glasgow-embedded.org/latest/intro.html
Catherine could extract the QSPI firmware, which is not the main outstanding thing from my current situation, but she could also extract the 48k Internal "ROM" from the YMW830 SWLL.
There's a mega.nz/file link in the discussion flow.
PSS-A50, PSS-F30, PSS-E30, SHS-300, PSR-F50, PSR-F51, PSR-F52, PSR-E253/YPT-255, PSR-E263/YPT-260, PSR-E273/YPT-270, PSR-E283/YPT-280 are all based on this YMW830 SWLL.
Now I'm wonderning if the 48k ROM is the same in all these products, especially for the PSS-A50, PSS-F30, PSS-E30 I own ? => answer is below in this post
The thing is that only the PSS-A50 has a dynamic touch response, while PSS-E30 and PSS-F30 are not managing dynamic touch in the SW, despite the fact the keyboards are the same from a HW point of view (dual switch per key - except some diodes shall be added on the PSS-E30/F30 PCB - PCB is the same for both pss-A50, PSS-F30, PSS-E30). PSS-A50 had an additional chip to manage the MIDI USB connection. Dynamic touch response is possible on PSS-E30/F30 ? That is a point I would like to investigate for a hack .
Then, also, a few days ago, someone made a great discovery : It is possible to access to an internal console of some Yamaha keyboards, using the USB connection and a Python script : https://github.com/portasynthinca3/swl01u
How awesome is that ?!
Porta/portasynthinca3 was also able to extract the firmwares using a FT232R-based JTAG dongle / OpenOCD (internal ROM of the SOC and external Flash), and performed a partial retro-engineering of her PSR-E433 firmware!
__Porta discovered that Yamaha made a shell that runs on top of MIDI SysEx messages, on the USB. She wrote a Python script in order to be able to access to the console.__
And that was not enough : she even was able to add/write her own arm code inside the ram, just by using the console. And the result is here : https://psi3.ru/blog/swl01u/
A GIT "issue" was open as a discussion flow, and it looks that so many Yamaha keyboards are compatible with this script !
Let's go back to the PSS-A50/PSS-F30/PSS-E30.
Earlier, when I went deeper inside the firmware/binary of the PSS-A50, I already suspected an old arm generation because of the typical arm 32 bits codeop starting with E1 xx xx xx / E5 xx xx xx / E9 xx xx xx / EA xx xx xx; which was confirmed by Ghidra and the best matching was Armv7; which confirmed the YMW830-V was a SOC based on a tone generator plus an Armv7 core. I suspected earlier a Renesas SH 'something' because I could see a string "Renesas", which was confusing when considering aother string "This code can only run on a Thumb compatible processor".
Of course, I was also intrigued by all these keywords I could also see this curious "login #0000" which made me thinking about an embedded console.
Recently, I try to make my JTAG/SWD probe with a blue-pill running BlackMagicProbe, but I did not success to have it talking with the YWM830. Don't know what is wrong on my side. I suspected the missing pull-up resistor on TDO, but no change when adding one.
Anyway, the shell.py from Porta "Works on PSS-A50".
My suggestion is to add this in the script, it helps to identify the right naming of the ports and in case, change them to fit your instrument (because PSS-A50 is : 'Digital Keyboard 0' / 'Digital Keyboard 1') :
print("MidO-IN =", mido.get_input_names(),"\n") print("MidO-OUT =", mido.get_output_names(),"\n")
login passwd? #0000 login OK > help logout help ? info ver stack perf-on perf-off perf-disp d dp d xxxxx d/s xxxxx m ADDRESS DATA m/b ADDRESS DATA m/w ADDRESS DATA m/l ADDRESS DATA regist voiceset ots func mdb backup chkprm freearea jobconid dispinfo swmask ioport getsw pushsw sendsw > info DevelopName PSS-A50 DevelopNumber #4007 Main DevelopNumber #4007 Make data & time MAY 07 2019 14:07:51 J/E Select English > ver Main Version 1.01 Boot Version 1.00 Style Version No Data Song Version 1.00 Param Version 1.00 Wave Version No Data Pattern Version No Data Unshi Version No Data Adss Version No Data Manufacturer : 0105 : YAMAHA. Product version : 0200 : V.2.00.00
Also, it's working with the PSS-E30 and with the PSS-F30 (not tested with the F30, but both same family as the PSS-A50, but without USB data interface). There's no data USB on the PSS-E30 / PSS-F30 products, but on the PCB, the Rx/Tx of the YMW830-V is easily reachable.
I could connect a cheap USB<->midi DIN (I had to modify it in order to extract the Rx/Tx at 3.3V levels - using a cheap level converter 5V<->3.3V). This USB/midi is seen as the following ports : 'USB MIDI Interface 0' / 'USB MIDI Interface 1'
And then, once connected to the PSS-E30 UART, same magic :
(and FYI, the internal 48k ROM content is the same for both PSS-A50, PSS-E30, PSS-F30)
login passwd? #0000 login OK > help logout help ? info ver stack perf-on perf-off perf-disp d dp d xxxxx d/s xxxxx m ADDRESS DATA m/b ADDRESS DATA m/w ADDRESS DATA m/l ADDRESS DATA regist voiceset ots func mdb backup chkprm freearea jobconid dispinfo swmask ioport getsw pushsw sendsw > ver Main Version 1.00 Boot Version 1.00 Style Version 1.00 Song Version 1.00 Param Version 1.00 Wave Version No Data Pattern Version No Data Unshi Version No Data Adss Version No Data Manufacturer : 0105 : YAMAHA. Product version : 0200 : V.2.00.00 > info DevelopName PSS-E30 DevelopNumber #4006 Main DevelopNumber #4006 Make data & time MAR 22 2019 10:59:11 J/E Select English
For curious people, here are the other main commands results for PSS-A50 :
Except these 3 ones, I'm a bit affraid to try : getsw pushsw sendsw
> perf-on Performance Start > perf-display Command Error > perf-disp -9Sec -8Sec -7Sec -6Sec -5Sec -4Sec -3Sec -2Sec -1Sec 0Sec (MAX=100%) ID 00 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 01 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 02 Task 1.8 1.5 1.5 1.5 1.5 1.7 1.1 1.6 1.6 1.8 ID 03 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.2 ID 04 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 05 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.2 0.1 0.5 ID 11 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 12 Task 0.2 0.2 0.1 0.2 0.2 0.1 0.1 0.1 0.1 0.5 ID 13 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 14 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 15 Task 13.3 13.7 13.3 13.2 13.4 13.1 13.7 13.4 13.2 13.2 ID 16 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 17 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 18 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 21 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 22 Task 0.9 1.5 0.6 1.2 1.2 1.1 1.8 0.6 1.5 0.8 ID 23 Task 1.7 2.0 2.2 1.8 2.2 2.2 1.8 2.2 1.8 2.3 ID 27 Task 2.5 4.3 3.6 3.8 4.7 2.5 4.4 3.9 3.3 5.8 ID 28 Task 1.9 1.5 1.4 1.4 1.4 1.7 1.3 1.6 1.6 1.6 ID 30 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 31 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 33 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 37 Task 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ID 43 Task 77.2 74.9 76.9 76.4 75.0 77.1 75.4 75.7 76.2 72.8 > > regist ========= Regist Parameter ========= Part param Main Dual Left On/Off : 127 000 000 Voice No. : 000 000 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 000 000 033 Volume : 100 100 090 Octave : 000 000 -001 Panpot : 064 064 064 Rev Depth : 008 008 000 Cho Depth : 000 000 000 Fil Cutoff : 000 000 000 Fil Reso : 000 000 000 Common Param Rev Type : 002 Cho Type : 001 Panel Sus : 064 Style No. : 000 Acmp On/Off: 000 Style Sect : 000 Acmp Volume: 255 Transpose : 000 Acmp Split : 054 Split Point: 054 Harm On/Off: 000 Harm Type : 001 Harm Volume: 255 Tempo : 120 Apg On/Off : 000 Apg Type : 000 ==================================== > > voiceset => Preset 1 Piano when PSS-A50 is turned on ======== Voiceset Parameter ======== Part param Main Dual Left On/Off : 127 000 000 Voice No. : 000 000 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 000 000 033 Volume : 100 100 090 Octave : 000 000 -001 Panpot : 064 064 064 Rev Depth : 008 008 000 Cho Depth : 000 000 000 Trns On/Off: 001 001 001 Common Param Cho Type : 001 Harm Type : 001 Harm Volume: 255 ==================================== > > voiceset => Preset 5 Organ ======== Voiceset Parameter ======== Part param Main Dual Left On/Off : 127 000 000 Voice No. : 004 004 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 016 016 033 Volume : 111 111 090 Octave : 000 000 -001 Panpot : 064 064 064 Rev Depth : 010 010 000 Cho Depth : 036 036 000 Trns On/Off: 001 001 001 Common Param Cho Type : 001 Harm Type : 001 Harm Volume: 255 ==================================== > > voiceset => Preset 12 Guitar ======== Voiceset Parameter ======== Part param Main Dual Left On/Off : 127 000 000 Voice No. : 011 011 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 027 027 033 Volume : 091 091 090 Octave : -001 -001 -001 Panpot : 064 064 064 Rev Depth : 011 011 000 Cho Depth : 064 064 000 Trns On/Off: 001 001 001 Common Param Cho Type : 001 Harm Type : 001 Harm Volume: 255 ==================================== > > PSS-A50 turned off and on again to have 1 Piano again > ots =========== OTS Parameter ========== Part param Main Dual Left On/Off : 127 000 000 Voice No. : 000 000 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 000 000 033 Volume : 100 100 090 Octave : 000 000 -001 Panpot : 064 064 064 Rev Depth : 008 008 000 Cho Depth : 000 000 000 Fil Cutoff : 000 000 000 Fil Reso : 000 000 000 Common Param Harm On/Off: 000 Harm Type : 001 Harm Volume: 255 Apg On/Off : 000 Apg Type : 000 ==================================== > > voiceset => Preset 14 Bass > ots =========== OTS Parameter ========== Part param Main Dual Left On/Off : 127 000 000 Voice No. : 013 013 014 Bank MSB : 000 000 000 Bank LSB : 000 000 000 Prg Change : 032 032 033 Volume : 080 080 090 Octave : -002 -002 -001 Panpot : 064 064 064 Rev Depth : 005 005 000 Cho Depth : 000 000 000 Fil Cutoff : 000 000 000 Fil Reso : 000 000 000 Common Param Harm On/Off: 000 Harm Type : 001 Harm Volume: 255 Apg On/Off : 000 Apg Type : 057 ==================================== > > func ======== Function Parameter ======== Part param Main Dual Left Volume : 080 080 090 Octave : -002 -002 -001 Cho Depth : 000 000 000 Common Param Rev Type : 002 Cho Type : 001 Panel Sus : 064 M EQ Type : 000 Acmp Volume: 255 Song Volume: 100 Transpose : 000 Master Tune: 000 Acmp Split : 054 Split Point: 054 Wide Type : 000 Rev T Level: 064 LocalOn/Off: 127 Ext Clock : 000 Metro Sig : 004 Metro Vol : 100 Demo Group : 001 Demo Play : 001 Demo Cancel: 000 A Pow Off : 030 Battery Sel: 000 ==================================== > PSS-A50 turned off and on again to have 1 Piano again > func ======== Function Parameter ======== Part param Main Dual Left Volume : 100 100 090 Octave : 000 000 -001 Cho Depth : 000 000 000 Common Param Rev Type : 002 Cho Type : 001 Panel Sus : 064 M EQ Type : 000 Acmp Volume: 255 Song Volume: 100 Transpose : 000 Master Tune: 000 Acmp Split : 054 Split Point: 054 Wide Type : 000 Rev T Level: 064 LocalOn/Off: 127 Ext Clock : 000 Metro Sig : 004 Metro Vol : 100 Demo Group : 001 Demo Play : 001 Demo Cancel: 000 A Pow Off : 030 Battery Sel: 000 ==================================== > > mdb Not Supported > > backup ======= Backup Ram Parameter ======= Part param Main Dual Left Common Param Panel Sus : 064 M EQ Type : 000 Master Tune: 000 Split Point: 054 Demo Cancel: 000 Master Vol : 008 ==================================== > > chkprm ========== Check Parameter ========= Part param Main Dual Left Common Param ==================================== > > freearea => "0" is strange, because the track recorder was far to be full Disk Free Area 0 > > jobconid Jobcon ID [Alert 000] [Popup 000] [Hold3 000] [Hold2 000] [Hold1 020] [Base 004] [Active 004] [Char Active Jobcon ID 004] > > dispinfo Display ID 002 (Jobcon ID:004) > > swmask Mask Pattern None > > ioport I/O Port Port0 0x000A6AEC > > getsw SW History new 052 (0x34) 052 (0x34) 053 (0x35) 052 (0x34) 052 (0x34) 052 (0x34) 052 (0x34) 141 (0x8D) 141 (0x8D) 141 (0x8D) old >