Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
364 lines (288 sloc) 13.7 KB

ET-312 Firmware / Hardware Reverse Engineering


This document contains notes about the reverse engineering efforts against the firmware of the ET-312B Electrostimulation Device.

This box has been on the market since 2001, and is still being sold. Firmware development has stopped around the year 2004, despite many known bugs and limitations. Still, the ET-312B remains one of the most popular E-Stim units. The motivation behind the reverse engineering efforts is allowing long standing bugs to be fixed, and its functionality to be extended by opening up firmware development to the community.

Since the firmware is closely tied to the physical implementation of the box, it is also necessary to map the ET-312 schematics and document the interaction between soft- and hardware. Because different hardware revisions exist, and not all of them are firmware compatible, the differences between revisions need to be analyzed.


  • Extract image from encrypted vendor firmware update files
  • Extract the bootloader from existing boxes, creating a raw image that can be used to flash a blank chip
  • Create custom firmware update files that can safely be flashed without require hardware modifications
  • Analyze firmware and map out any hidden functionality
  • Create a system to easily patch/augment existing firmware
  • Create full schematics, including differences between board revisions
  • Decompile and annotate the stock firmware
  • Create an easy to use firmware development toolchain
  • Create a firmware version that works on all box revisions
  • Re-Write a custom firmware functionally equivalent to stock firmare as a basis for future developments

Hardware Overview

Main Processor

The ET-312B runs on an ATMega16 microcontroller. There is no external memory, everything exists in memory on the chip. From the factory, all fuses are set on the chip, locking out JTAG access or the ability to read out the flash or bootloader via SPI. Starting with V1.4 or higher, the main firmware is field upgradeable via the built in serial port. The only way to upgrade older units or to flash your own bootloader is to unsolder the microcontroller, and either erase it with an external programmer or replace it with your own chip.

Note that these older ATMEGA processors require calibration for their internal RC oscillator as used. If programming a blank chip you first need to read the calibration bytes of that part (i.e. using avrdude -t “dump calibration” the fourth byte is the calibration byte for 8MHz). Then program that byte into 0x3fff in your firmware. These bytes will differ on different chips even from the same batch. The firmware reads that byte to set OSCCAL on startup. If the byte is inaccurate various problems and failures will occur related to timing, interrupts, and serial communication.

The I/O Pins are used as follows:

01 PB0    Pulse A Push
02 PB1    Pulse A Pull
03 PB2    Pulse B Push
04 PB3    Pulse B Pull
05 PB4    Radio (U6 Pin2)
06 PB5    DAC / Data (U8 Pin4)
07 PB6    Radio (U6 Pin6)
08 PB7    DAC / Clock (U8 Pin5) + Radio (U6 Pin7)
09 RESET  Reset
10 VCC    +5V
11 GND    GND
12 XTAL2  Quartz (X1 Pin 1)
13 XTAL1  Quartz (X1 Pin 3)
16 PD2    Audio Digital A (U2 Pin 14)
17 PD3    Audio Digital B (U2 Pin 8)
18 PD4    DAC / CS (U8 Pin3)
19 PD5    LED Channel B (low active)
20 PD6    LED CHannel A (low active)
21 PD7    LCD Backlight (LCD Pin 16)
22 PC0    MUX LCD/Switches (U3 Pin 5,6,12,13)
23 PC1    (LCD Pin 5 = R/W)
24 PC2    (LCD Pin 6 = ENABLE)
25 PC3    (LCD Pin 4 = RS)
26 PC4    LCD Data Bus 4 (LCD Pin 11 = DB4) / Button Down (via U3)
27 PC5    LCD Data Bus 5 (LCD Pin 12 = DB5) / Button OK   (via U3)
28 PC6    LCD Data Bus 6 (LCD Pin 13 = DB6) / Button Up   (via U3)
29 PC7    LCD Data Bus 7 (LCD Pin 14 = DB7) / Button Menu (via U3)
30 AVCC   +5V
31 GND    GND

Display / LEDs / Buttons

The Display is a Winstar WH1602A two-line 16 character LCD. It has the usual hd44780/st066u interface, but the pins are out of order. It is used in 4-bit mode and can be conrolled via ports PC1-PC7. The backlight is controlled via PD7. There are two red LEDs in the front panel connected to D5/D6, low active. The front panel tact switches share lines PC4-PC7 and are multiplexed with a cd4066 switch IC which is connected to port PC0. That means, you have to pull PC0 low each time you want to read the buttons, and high when you want to write to the LCD.


The A/B Level Potentiometers go straight to ADC5 and ADC6, so they are stricly used as input devices. They have no other electrical function. The “Multi Adjust” pot is a complicated afair. It is a stereo pot which sets both the audio input level and certain program parameters inside the MCU. The audio signal is directly routed through the pot, which acts as a straightforward volume adjustment. Additionally, there is a bias voltage added to channel A, which is later routed to ADC1 so the firmware can measure the position of the pot independenty from any audio input.

Audio Input

You night have noticed that the two audio channels never seem to react quite the same, even if you supply them with exactly the same input level. This is because there is a bit of trickery going on. Channel A is AC coupled, and Channel B is DC coupled, which enables Channel B to be used as a sort of wired remote control by feeding between 0 and 2V DC into the audio jack. This feature is actually documented in the users manual, but it is only available on Channel B - because Channel A already uses DC internally to detect the multi adjust potentiometer position. The microphone signal is mixed in with the Channel B Audio input, and the amplification is appropriate for a typial electret “Soundblaster” microphone.

Power Supply

The box runs on a main supply voltage between 12 and 15V, either supplied by an internal 12000mAh Lead/Acid gel battery or an external charger. There are two versions of the box “ET-312” and “ET-312B” and only the latter will have the built in battery. The power supply will run the box at 12V, but 15V are required to charge the battery. Charge current is regulated via a LM2941CT. Internally, the 12V rails is regulated down to a 5V rail for the digital part via a 78m05 and to two 9V rails, one for each output channel, via a 78m09.

The power supply voltages can be monitored via the MCU through ADC2 (External Power) and ADC3 (Battery Power). The firmware will shut the unit down when undervoltage is detected.

Output Stage

The output stage is identical for both channels. The input voltage is supplied via an external DAC, which differes between board revisions. Boards up to Rev.F use the MAX548, newer revisions use the LTC1661. The two DACs are not compatible, and require differences in Firmware. Data, Clock and Chip Select go to PB5, PB7 and PD4. The actual power stage is similar to an amplifier in push/pull configuration, each side driven by a digital pin on the MCU (PB0-PB3). A step up transformer (approx 1:4.7 ratio) then feeds the electrodes.

Radio Control

Earlier Boards (Revision D+E) have a few unpopulated pads, and their layout and silkscreen markers hint at a planned radio module that was apparantly never implemented - most likely for economical reasons. The layout suggests that it might fit a standard 443 Mhz module like it is used in the ET302. It is connected via the unpopulated U6 to PB4, PB6 and PB7. If the software side is implemented, it might be possible to retrofit older units.

Serial Port

The “Link” jack goes through a buffer circuit directly to the UART lines of the MCU. The default transfer settings are 19200/8/n/1. The serial port can be used to control the box during operation, see for documentation. In bootloader mode, it can also be used to upload firmware updates.

Hardware Revisions

These are the hardware revisions that have been spotted in the wild so far. If your box comes with Firmware V1.5 or earlier, you will likely have board Revision E or earlier. The only way to determine the exact hardware revision is to open the box, and look at the version number on the silkscreen.

Revision D

  • Silkscreen: Rev.D / (C) 2001 ETP
  • DAC: MAX648
  • Firmware: 1.0-1.3 (Possibly compatible to 1.4/1.5, but no upgrade via serial)
  • Unpopulated Radio Module: Yes
  • Chips covered with potting compound: Yes

Revision E

  • Silkscreen: Rev.E / (C) 2001 ETP
  • DAC: MAX648
  • Firmware: 1.4-1.5
  • Unpopulated Radio Module: Yes
  • Chips covered with potting compound: Yes

Rev G

  • Silkscreen: Rev.G (C) 2001-2003 ETP
  • DAC: LTC1661
  • Firmware: 1.6
  • Unpopulated Radio Module: No
  • Chips covered with potting compound: No

Rev H

  • Silkscreen: Rev.H (C) 2001-2006 ETP
  • DAC: LTC1661
  • Firmware: 1.6
  • Unpopulated Radio Module: No
  • Chips covered with potting compound: No

Rev I

  • Silkscreen: Rev.I (C) 2001-2014 ETP
  • DAC: LTC1661
  • Firmware: 1.6
  • Unpopulated Radio Module: No
  • Chips covered with potting compound: No

Software Revisions

(This information is gathered from internal changelogs sent to beta testers and through firmware analysis)

Known Versions

v1.0 (2001)

  • Initial Release




  • Improved battery charge display on power up.
  • Improved audio processing for phaser/rxtc/stereostim files
  • A few modes were tweaked slightly


  • Hardware/firmware modified to allow field firmware upgrades
  • Bug fixed in random number generation routine
  • MultiAdjust calculation improved

V1.5 (2002 / 2003):

  • Bug fixed that causes a shutdown condition on a very small number of units

V1.6 (2004):

  • Support new hardware revision.
  • Cures “Failure 77” error on new hardware revision


There are at least three incompatible hardware revisions. Old boxes run firmware v1.3 or earlier, and do not allow field updates via serial. Some boxes will run firmware v1.4 and v1.5 and allow field updates. The newest hardware revision only run v1.6.


There seem to be two variations of v1.5 Firmware out in the wild. They show the same version Number but different copyright dates. The v1.5 image from the ErosTek download site says:

(c) '02 ErosTek
ErosTek ET-312B
SelfTest OK V1.5

Some boxes apparently have a newer date, but the same revision:

(c) '03 ErosTek
ErosTek ET-312B
SelfTest OK V1.5

ErosTek urges the users of these boxes to upgrade to V1.6:

(c) '04 ErosTek
ErosTek ET-312B
SelfTest OK V1.6


Two versions of the firmware, for v1.5 and v1.6, are available via the firmware upgrade website:

These files (312-15.upg and 312-16.upg), are also available in the Erosoutsider Repo.


The firmware files use a simple XOR stream cypher. Bytes are encoded in groups of three, with a different transform being performed on each key byte in the group. In python it looks roughly like this (check for the full story):

KEYS = [0x65, 0xed, 0x83]
IV = [0xb9, 0xfe, 0x8f]

def decrypt(self):
       funcs = {0: lambda x: ((x ^ 0x62) + 0x41) & 0xff,
                1: lambda x: (n >> 4) | ((n & 0x0f) << 4),
                2: lambda x: x}

       for i in range(0, len(self.input_file)):
           n = self.input_file[i]
           choice = i % 3
           output = funcs[choice](n) ^ self.iv[choice] ^ self.KEYS[choice]
           self.iv[choice] = n


The firmware image itself containts three checksum bytes at offset 0x3DF0 which are checked by the bootloader. The first byte is a simple XOR of all bytes from 0x0000-0x3DEF. Byte two and three are an equally simple 16-bit sum of all byte values.

def generate_crc(self):
    xor = 0
    add = 0
    for c in range(15872 - 16):
        xor ^= self.input_file[c]
        add += self.input_file[c]
    return [xor, (add & 0xff), ((add >> 8) & 0xff)]

Upload/Upgrade Process

To upgrade the firmware on the box, you need to first enter bootloader mode by holding the MENU/UP buttons while turning the unit on. The upgrade file is then simply transferred via the XMODEM protocol over the serial line. (Bits per second=19200, Data bits=8, Parity=None, Stop bits=1, Flow control=None). Only the original XMODEM with 128 byte packets will work, 1024 byte packets are not supported. The Ch A and Ch B lights will flash randomly as the data is transferred to the ET-312. DO NOT interrupt this process in any way. When the transfer is completed, the ET-312 will reset and the display should show the new version of the software.

Error Messages

4Linking boxes failed or communications dropped
10Program contains unknown module number
15Maths error like divide by 0 or wrong random parameters
16Power level is set to invalid value
20FET startup calibration failed
21PSU voltage is too high
72Serial communications buffer is full
80Call to an unknown function
You can’t perform that action at this time.