My EP-133 K.O. II boots as an EP-40 riddim now. It took four bytes

m_kos1 pts0 comments

My K.O. II boots as a riddim now. It took four bytes.

Press ESC to close

Or check our Popular Categories...

Physical EP-133 unit with the EP-40 riddim firmware-exclusive Supertone engine loaded, presenting as an EP-40 riddim to an OP-1 Field connected over USB.

Teenage Engineering sells the EP-133 and the EP-40, two awesome instruments with a lot of crossover similarities. After a little exploring, I found out that the only thing preventing one from running the firmware of the other is a four-byte field in the firmware file's header.

Note: This has only been tested on one legacy 64 MiB EP-133. I'm not affliated with teenage engineering, and they think it's a bad idea to do this.

I agree - don't do it! Here's how I did it to mine.

This is Unsupported. I'll be repeating this a lot throughout: TE's engineering team asked that I say this plainly: cross-flashing is unsupported. Field units ship different NOR flash types and densities, and you are risking incompatibility, data loss, a brick, and your warranty. Everything below happened on one legacy 64 MiB EP-133. The walkthrough of this discovery process is shared because of its interest from a technology perspective, and the corresponding tool that I built for my personal use is shared because I've learned some fail-safe tests that helped me throughout my testing that may be of interest for others exploring similar research.

How it started<br>The EP-133 (k.o. II) and the EP-40 (riddim) share a lot of the same features. They have the same body, same screen, same pads. But the newer riddim ships with some unique features like looping, multisample, and the Supertone synth engine. These sounded like really cool features to me, and I was curious what it'd be like to play with them.<br>I own an EP-133 and, looking at it recently, I wondered if it could just... run the device's other firmware. Turns out, yeah, and it's actually not too complicated. Teenage Engineering, who after I shared this information with them asked that I communicate warnings about how this is unsupported and would void your unit's warranty, hands people pretty much all the tools they'd need to figure this out, too. Just had to figure out where to look.<br>Reviewing the firmware files<br>TE hosts a public updater at teenage.engineering/apps/update. It runs entirely in the browser and talks to the device over USB, which means you can watch how it works using DevTools.<br>I opened the tool without my EP-133 plugged in, switched to Network, and reloaded. One request stood out: a GET for releases.json. That's the firmware catalog, listing products by SKU, each with an fw_url ending in .tfw.

Elements<br>Network<br>Sources<br>Console<br>https://teenage.engineering/apps/update

GET<br>apps/update/assets/index-….js<br>200<br>js

GET<br>/_software/releases.json<br>200<br>json

"devices": [<br>"sku": "TE032AS001", // EP-133 k.o. II<br>"version": "2.5.1",<br>"fw_url": "/_software/ep-133/ep-133_firmware_2_5_1.tfw"<br>},<br>"sku": "TE032AS006", // EP-40 riddim<br>"version": "2.5.1",<br>"fw_url": "/_software/ep-40/ep-40_firmware_2_5_1.tfw"

Fig. 1 · Direct download:<br>https://teenage.engineering/_software/releases.json.<br>Maps each SKU to a fw_url. The two I used:<br>…/ep-133_firmware_2_5_1.tfw<br>(TE032AS001) and<br>…/ep-40_firmware_2_5_1.tfw<br>(TE032AS006), both 2.5.1.

Two files stood out, both at version 2.5.1 and available to download without requiring an account or connected device.<br>Exploring TE's update tool<br>I plugged the EP-133 in, opened the page, allowed WebMIDI with sysex. It found the device and showed the normal card: serial, OS, SKU, etc.<br>Updating firmware, unfortunately, doesn't natively ask you to provide a file. However, watching Network showed the page fetches releases.json on load, and when you hit Update it downloads whichever package in that json matches the SKU of the thing you plugged in.<br>The tool also loads a lot of easily viewable code to the user's browser.<br>Reading the page's own JavaScript<br>Same Network panel, the app's main script for me was titled index-CFniztty.js (filename post index- is content-hashed and will change per person) and comes in at about 625 KB. I downloaded and ran rg over it.

rg -n 'releases.json|fw_url|not compatible' index-CFniztty.js

# file: teenage.engineering/apps/update/assets/index-CFniztty.js<br>fetch("/_software/releases.json") # ~byte 620406<br>const s=t||this.props.fw.fw_url # ~byte 598408<br>firmware not compatible with this device # ~byte 599860

Fig. 2 · Lots of solid info in<br>index-CFniztty.js.

The Update path is the short one. upgradeDevice hands their DFU perform either a dropped file or, normally, this.props.fw.fw_url straight from the catalog:

// Source: /apps/update/assets/index-CFniztty.js (search: "upgradeDevice")<br>// Minified; line breaks added only for reading.<br>async upgradeDevice(t=!1){<br>const r=t?this.state.dropFW.version:this.props.fw.version;<br>const s=t||this.props.fw.fw_url;<br>await src_default.perform(this.props.device.serial,s,this.onProgress);

Fig. 3 · Stock Update sends whatever fw_url the catalog gave for the...

update fw_url firmware engineering json riddim

Related Articles