This page is a collection of software and documentation related to the Daum Premium 8i indoor bike. The bike has some properties that makes it an interesting research target:
mw001
.However, there a number undocumented areas:
M70
command used by online training software is not documented. This
makes it hard to add Daum support to
GoldenCheetah, for example.On this page I'm going to document my findings and progress.
Update (2024-03-03): Updated links
The bike uses EPP files to control the training. E.g. the duration and power curve or the elevation over distance curve for a training can be defined with an EPP file. Daum provides the program DPPEdit for Windows (32bit), last release January 2008, to create and modify EPP files. It only allows to import HAC4 elevation and heart rate profiles.
To be able to convert GPX files directly into EPP elevation profiles, I've reverse engineered the file format and created simple converter in Python. The eppconvert package can be found on GitHub and on PyPI.
By default the telnet demon is enabled on port 23. Unfortunately there
is no username/password published. Enabling root access is fairly
simple though. Search the mw001
application that is part of the
update zip file for consecutive sequences of ASCII numbers:
strings mw001 | egrep '^[0-9]{6}$'
One of them is the PIN for the service menu. Within the service menu there is an option to enable telnet, which will also display the configured root password. I believe the password is unique for each bike or will be generated when enabling telnet.
A word of warning: the settings exposed in the service menu could potentially damage your bike. Also root access to the device can make the control panel unbootable and you could void your warranty. So stay away from these settings if you can't risk that.
TCP port 51955 runs the control protocol. The socket belongs to the mw001 application that also controls the user interface on the control panel.
Parts of the control protocol are documented. I've done some initial tcpdump of the communication between ergo_win race and the bike. During the first few exchanges some data is transferred that looks very much like an EPP file without parts of the header. Needs further analysis.
The control panel runs linux-2.4.21 with some (published) modifications for the SoC.
SoC: Samsung S3C2410X, ARM9TDMI/ARM920T core (ARMv4T). The documentation from Samsung is not online anymore, but can be found via archive.org.
I've initially tried running some ARM binaries extracted from Debian 3.1 udebs. I've copied the binaries and additional libraries to the SD-card and used LD_LIBRARY_PATH to not modify the root filesystem. Simple binaries work, but there are limitations. Building the arm toolchain and cross-compiling is more promising.
The crosstool based toolchain that is published by Daum still
builds with some tweaks, even though the software is more than 10
years old. The compilation starting point is the demo.sh
in the
patched crosstool directory. I've got a working arm9tdmi
cross-compiler and glibc on Fedora 28. Fedora is especially useful
here since it still contains gcc-3.4, which is hard to find for
other distributions and is the only gcc version I got the toolchain
compiled with. Some help for compiling the toolchain
can be found in my GitHub repository
With the cross compiler I've built strace-4.5.8 and OpenSSH-7.4p1
for further exploration. They both work fine. To make it run nice
from the SD-card, use --prefix=/card/tools
or similar.
Initially I planned to attach an ANT stick directly to the Daum bike for remote control. For that I wrote a simple kernel driver, which works somewhat. So cross-compiling kernel modules works as well. For now this has been postponed as I first need to figure out how the remote control protocol works.
The Daum Cockpit three main applications that communicate with each other via pipes or files and with the hardware via device drivers. The following diagram illustrates the relationship:
The main application mw001 controls the GUI via the fb0 framebuffer device. It also handles remote control via port 51955, USB-Serial or Daum bluetooth adapter.
The serial connection ttyS1 is almost certainly used for communication to the brake system. For example when adjusting the power setting to 33 Watts, you can observe the following data with strace on ttyS1:
root@secutest:~>ls -l /proc/131/fd # PID 131 == mw001 ... lrwx------ 1 root root 64 May 21 10:55 7 -> /dev/ttyS1 ... root@secutest:~>/card/binaries/bin/strace -e write -e write=7 -p 131 ... write(7, "R\0!\0", 4) = 4 | 00000 52 00 21 00 R.!. |
It is possible to stop and restart the mw001 app without redirecting stdout/stderr to /dev/null. That way debug output can be observed. To restart mw001 in foreground:
# terminate running mw001 kill $(ls -l /proc/*/exe | grep mw001 | cut -d/ -f3) # start new instance in foreground cd /application && /application/mw001
Here is an example output of the mw001 application:
MwUserInit: priority = -10 src_fb: visual = 2 scr_fb: bpp = 8 rows 240, cols 320, xdpcm 14, ydpcm 5, planes 1, bpp 8, ncolors 256, fonts 11, buttons 0, modifiers 0, pixtype 7, portrait 0, fbdriver 1, rmask 00e0, gmask 001c, bmask 0003, xpos 0, ypos 0 vs_width 1520, vs_height 36736, ws_width 34224, ws_height 0 MiddleWareDeviceSettings_Initialize: 1 Language_AddLanguage languages/deutsch Language_AddLanguage languages/english Language_AddLanguage languages/espanol Language_AddLanguage languages/francais Language_AddLanguage languages/italiano adding languages/suomi failed MiddleWareIniFile_Initialize: 1 MiddleWareMsp_Initialize: device = ergo_bike premium8 MiddleWareMsp_Initialize: 1 MiddleWareMsp_GetDeviceLimit: min = 20.0, max = 1000.0, def = 20.0 (Watt) MiddleWareMsp_GetDeviceLimit: min = 0.0, max = 0.0, def = 0.0 (Slope) MiddleWareMsp_GetDeviceLimit: min = 0.0, max = 99.9, def = 10.0 (Speed) MiddleWareMsp_GetDeviceLimit: min = 0.0, max = 0.0, def = 0.0 (Acceleration) MiddleWareDeviceInfo_Initialize: 1 MiddleWareDeviceInfo_Initialize: 1 MiddleWareBattery_Initialize: 1 MiddleWareRelax_Initialize: 1 ------------------------------------- wattcount = 41 pulsCount = 13 cardioPlusCount = 3 rpmCount = 12 distanceCount = 68 forceCount = 12 speedCount = 0 speedSlopeCount = 0 ------------------------------------- skipped = 102 ------------------------------------- MiddleWareFactory_Initialize: 1 MiddleWareNetrace_Initialize: 1 EMC2: unmounted /card MiddleWareEmc2_Initialize: 1 MiddleWareEmc2Ini_Initialize: 1 MiddleWareBodyData_Initialize: 1 CoachingTyp: 0 CoachingState: 0 MiddleWareCoaching_Initialize: 1 MiddleWareDsp_Initialize: 1 *** MiddleWareVolume_DetectDACType: detected DAC3555A subadr: 02 avol = 0000 gcfg written successfully subadr: 02 avol = 2C2C MiddleWareVolume_Initialize: 1 EMC2: card insert/remove => unmounting!!! EMC2: trying mount... MiddleWareEmc2_GetCardIdInternal: 03-53-44-53-44-30-31-47-80-01-D9-94-EC-00-A4-1B EMC2: mounted /dev/mmc1 => /card EMC2: *** MiddleWareEmc2_MountAction *** EMC2: reading /card/data/user/userdata => sizeof(TERGO_MEMO_DEVICE_DATA): 36 version 3 => OK (converted v3->v3) EMC2: reading /card/data/user/ergo_bike/userdata.device => version 4 => OK CoachingTyp: 0 CoachingState: 1 MiddleWareCoaching_Initialize: 1 Checking training results: removing empty result /card/data/result/ergo_bike/0000000000000072 MiddleWareDeviceInfo_Initialize: 1 MiddleWareMp3_CardPlugged: starting playlist transfer... file: /card/mp3/Relaxmelodie.mp3 MiddleWareMp3_CardPlugged: ...finished playlist transfer ------------------------------------- wattcount = 3 pulsCount = 0 cardioPlusCount = 0 rpmCount = 0 distanceCount = 9 forceCount = 0 speedCount = 0 speedSlopeCount = 0 ------------------------------------- skipped = 0 ------------------------------------- PPL_LoadUserPremiumPrograms: 5 programs loaded PPL_LoadUserPremiumPrograms: 5 programs loaded MiddleWarePulse_Initialize: 1 MiddleWareBP_Initialize: 1 MiddleWareRc_Initialize: 1 MiddleWareDemo_Initialize: 1 *** WM_CURRENT_TRAINING_SET: wp=0, showStartMsg=1 MiddleWareTrainingLimits_ExternalPDActive: 0 *** WM_CURRENT_TRAINING_SET: wp=2788616, showStartMsg=1 ****************** MiddleWareTraining_Start: at 00006757ms => Manuelles Training (Watt) *** MiddleWareTraining_Start: noProgramAdaption = 0 DisableSplashScreen: already disabled or old kernel without /proc/splash_scr RcIoTcpIp_OpenSocket: server socket 16
To open the cockpit you need unmount the cockpit from the bike (4 screws), unplug the cables and open the cockpit case (5 screws). The PCB with SD-Card slot at the top looks like this (click to enlarge):
In right upper corner there is a 4-pin header with the serial port of the ARM SoC which is used as console/ttyS0. The GND/RX/TX pin locations are marked in the following picture:
To connect to the serial port, use a 3.3V USB-serial adapter and a terminal program with the following settings:
Here is an example boot log:
Loading Kernel: ## Booting image Image Name: linux-2.4.21 Image Type: ARM Linux Kernel Image (lzo compressed) Data Size: 638555 Bytes = 623 kB = 0.6 MB Load Address: 0x30008000 Entry Point: 0x30008000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK Starting kernel ... Linux version 2.4.21-rmk1-swl8 (gerd@daum-pc-10) (gcc version 3.3.2) #28 Do Mär 3 19:35:18 CET 2005 CPU: S3C2410(Arm920T)id(wb) revision 0 Machine: SAMSUNG ELECTRONICS Co., Ltd On node 0 totalpages: 16384 zone(0): 16384 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: root=/dev/mtdblock2 rootfstype=yaffs console=ttyS0,115200 Console: colour dummy device 80x30 Calibrating delay loop... 67.37 BogoMIPS Memory: 64MB = 64MB total Memory: 63348KB available (1048K code, 263K data, 56K init) Dentry cache hash table entries: 8192 (order: 4, 65536 bytes) Inode cache hash table entries: 4096 (order: 3, 32768 bytes) Mount cache hash table entries: 512 (order: 0, 4096 bytes) Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes) Page-cache hash table entries: 16384 (order: 4, 65536 bytes) POSIX conformance testing by UNIFIX Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket CPU clock = 270.000 Mhz, HCLK = 135.000 Mhz, PCLK = 67.500000 Mhz Starting kswapd ttyS0 at MMIO 0xe0000000 (irq = 52) is a S3C2410 ttyS1 at MMIO 0xe0004000 (irq = 55) is a S3C2410 Console: switching to colour frame buffer device 40x30 pty: 256 Unix98 ptys configured eth0: cs8900 rev K found at 0xf0000300 [Cirrus EEPROM] cs89x0 media RJ-45, IRQ 3, programmed I/O, MAC 00:12:64:00:66:ea loop: loaded (max 8 devices) NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V) Using static partition definition Creating 3 MTD partitions on "s3c2410-nand": 0x00000000-0x00004000 : "nboot" 0x00004000-0x00200000 : "bootfiles" 0x00200000-0x04000000 : "system" NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP IP: routing cache hash table of 512 buckets, 4Kbytes TCP: Hash tables configured (established 4096 bind 8192) NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. NetWinder Floating Point Emulator V0.97 (double precision) yaffs: dev is 7938 name is "1f:02" VFS: Mounted root (yaffs filesystem). Freeing init memory: 56K init started: BusyBox v0.60.5 (2004.04.30-15:15+0000) multi-call binary This is rc.sysinit, which is run once at boot time. yaffs: dev is 7937 name is "1f:01" Testing for runonce.sh... Creating ram disk... RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize 64 inodes 128 blocks Firstdatazone=6 (6) Zonesize=1024 Maxsize=268966912 Configuring Network: eth0: using full-duplex 10Base-T (RJ-45) Starting Internetservices Loading daum modules... Samsung S3C2410X (i2c) algorithm module version 2.6.1 (20010830) iic_s3c2410_init: Samsung S3C2410X iic adapter module version 2.6.1 (20010830) enable_irq(27) unbalanced from c48271f0 s3c2410_init: Initialized IIC on S3C2410X, 64kHz clock iic_s3c2410_init: initialized iic-bus at 0x54000000. i2c-dev.o: Registered 'Samsung S3C2410X IIC adapter' as minor 0 Using daumkey.o Symbol version prefix '' Warning: loading daumkey.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information abou** tainted module* Warning: load ng daumkey.o wiDl taint the kerAUel: forced load M Keyboard Support by Gerd Mitlaender driver version 2.00 loaded Module daumkey loaded, with warnings Using mousewheel.o Symbol version prefix '' Warning: loading mousewheel.o will taint the kernel: non-GPL license - DAUM-LICENCE See http://www.tux.org/lkml/#export-taintLd for informatioan about tainteddmodules Warnini: loading mousenheel.o will taigt the kernel: forced load Mousewheel driver from Rolf Freitag, Daum Electronic GmbH. Module mousewheel loaded, with warnings Using ./adc_timer.o Symbol version prefix '' Warning: loading ./adc_timer.o will taint the kernel: non-GPL license - DAUM-LICENCE See http://www.tux.org/lkml/#export-tainted for informatRon about taintee modules Warnipg: loading ./ade_timer.o will taint the kernel: forced load ted sequence of channels (RSC) mode ADC driver + second system timer starting. RSC driver from Rolf Freitag, daum electronic gmbh. V 2.0 2005-02-21 by Gerd Mitlaender Module adc_timer loaded, with warnings Using digital_puls.o Symbol version prefix '' Warning: loading digital_puls.o will taint the kernel: non-GPL license - DAUM-LICENCE See http://www.tux.org/lkml/#export-tainted for information about taintDd modules Warning: loading diggital_puls.o willttaint the kernea: forced load l Pulse driver strarting. Digital Pulse driver from Rolf Freitag, Daum Electronic GmbH. Module digital_puls loaded, with warnings Using ./rtc_ds1339.o Symbol version prefix '' Warning: loading ./rtc_ds1339.o will taint the kernel: forced load See http://www.tux.org/lkml/#export-tainted for informatioD about tainted modules S1339 I2C Real Time Clock Driver v 0.02 loaded *** RTC Support by Rolf Freitag, daum electronic GmbH. Module rtc_ds1339 loaded, with warnings S3C2410 audio driver initialized DAC3550A audio driver initialized usb.c: registered new driver hub usb-ohci.c: USB OHCI at membase 0xd9000000, IRQ 26 usb.c: new USB bus registered, assigned bus number 1 hub.c: USB hub found hub.c: 2 ports detected SCSI subsystem driver Revision: 1.00 Initializing USB Mass Storage driver... usb.c: registered new driver usb-storage USB Mass Storage support registered. MMC/SD Slot initialized SecureDigital (SD) Card identified. first_minor 0x00000000 Partition check: mmc_sda: mmc_sda1 dev->sizes[i] 0x00000000 usb.c: registered new driver serial usbserial.c: USB Serial Driver core v1.4 usbserial.c: USB Serial support registered for FTDI SIO usbserial.c: USB Serial support registered for FTDI 8U232AM Compatible usbserial.c: USB Serial support registered for FTDI FT232BM Compatible ftdi_sio.c: v1.3.2:USB FTDI Serial Converters Driver Loading daum applications... Fri Apr 24 19:03:00 UTC 2020 Starting mp3 server application... Starting analog pulse application... *** mp3 player for two streams based on madplay *** (c) 2004 daum electronic gmbh Starting daum main application... secutest login:
M70
command). While the Daum server for online
training (srv3.daum.noris.de) was still available, I did some
network traces containing some sample M70
packets. Those should
be useful, but there are other options as well.