HD200_UPG.SYS is the main firmware file. During upgrade it is written to flash 0x00000000 - 0x000FFFFF

Looking at flash write routines there is "memory hole" in flash 0x100000 - 0x104A00 - there is no routine writing to this location. However string printing routines reads fonts bitmaps for wchar less than 0x24F there so this must be programmed in factory and never touched.

Last two sectors of flash are used to save some config settings (and resume data)

Start sequence

I have started the dissasembly of firmware upgrade files. The file HD200_UPG.SYS (1.30.05) looks promising. After short initialization routines the code from flash is copied to dram and sram according to the table below. Then program jumps to the entry point located in dram.

source

destination

length (words)

0xb0a-0xf09

0x10000000-0x100003FF

0x200

0xf0a-0x16a1

0x10000400-0x10000b97

0x3cc

0x16a2-0x1b6b

0x10000ba0-0x10001069

0x265

0x1b6c-0x1fcf

0x100010f0-0x10001553

0x232

0x1fd0-0x6b9b

0x100066e0-0x1000b2ab

0x25e6

0x6b9c-0xa6d3

0x1000b2ac-0x1000ede3

0x1d9c

0xa6d4-0xc3eb

0x30BE3C20-0x30BE5937

0xe8c

0xC3EC-0x4b1f7

0x30BE5938-0x30c24743

0x1f706

0x4B1F8-0x6c6e3

0x30C24744-0x30C45c2f

0x10a76

0x6C6E4-0x6d503

0x30C45C30-0x30C46a4f

0x710

0x6D504-0x6f01b

0x30C46A50-0x30c48567

0xd8c

0x6f01c-0x72561

0x30c48a70-0x30c4bfb5

0x1aa3

0x72562-0x7a0dc

0x30c4e361-0x30c55eda

0x3dbd + 1byte

0x7a0dd-0x7af14

0x30c55ee0-0x30c56d17

0x71c

0x7af15-0x7bc78

0x30c56d20-0x30c57a83

0x6b2

0x7bc79-0x7e78a

0x30c57a90-0x30c5a5a1

0x1589

0x7e78b-0x807e2

0x30c5a5b0-0x30c5c607

0x102c

0x807e3-0x81bfa

0x30c5c610-0x30c5da27

0xa0c

0x81bfb-0x82d3e

0x30c5da30-0x30c5eb73

0x8a2

0x82d3f-0x86c3e

0x30c5eb80-0x30c62a7f

0x1f80

0x86c3f-0x93ace

0x30c62a80-0x30c6e40f

0x6748

0x92e33-0xb1d20

0x30c6e410-0x30c70afd

0xf777

0x95921-0x963f4

0x30c70b00-0x30c715d3

0x56a

0x95ff5-0x9a002

0x100066e0-0x1000a6ed

0x2007

0x9a003-0x9b0da

0x1000f60c-0x100106e3

0x86c

0x980db-0xaf016

0x30c75b80-0x30c8cabb

0xb79e

0xb2017-0xb25e2

0x30c8cac0-0x30c8d08b

0x2e6

Memory map

address range

length (bytes)

description

0x00000000-0x001FFFFF

0x200000

chip select 0 (2MB Flash)

0x10000000-0x1000FFFF

0x10000

sram1 64k

0x10010000-0x10017FFF

0x8000

sram0 32k

0x30000000-0x30FFFFFF

0x1000000

sdram 16M

0x40000000

mbar

0x50000000

chip select 3 (LCD)

0x60000000

chip select 2 (IDE)

0x80000000

mbar2

exception vector table is located in sram 0x10000000-0x100003FF

LCD initialization

The LCD initialization routine (0x30BF81A0) looks consistent with datasheet: First we have setting GPO34 low, delay, setting GPO34 high which I think is hardware reset sequence. Than we write to CS3

T means it was tested with simple code injected into test mode (assignment of F/I/O and E comes mostly from this readings also)

"*" indicates that this GPIO or function is actually implemented by two pins on the physical package -- one dedicated input pin and one dedicated output. This means that this logical bit can serve two functions simultaneously. There's only one bit that decides function vs. GPIO, so the composite pin must either both be function pins or a GPI and GPO pin.

"**" - Pulling GPO28 low turns off backlight. To turn it on again it is necessary to produce some waveform. Basically it is GPO28 low, delay, n times (GPO28 high, GPO28 low), GPO28 high. I am unable to reproduce this correctly. If I use calls to OF functions toggling GPIO bits it works. Mybe this is some timing issue? The brightness of backlight is related to how many high to low transtions of GPO28 was made. OF firmware uses 20 transitions.Edit: running the same procedure in rockbox bootloader works.

"***" - checked after desoldering MCU and LD245A? buffer from defective HD300 mainboard. Dissasembly reveals that both players share the same code for USB handling

Battery charging

Charging is done by LTC1733 chip. It charges with 100mA current (15k Ohm PROG resistor) and with 6 hours timeout (0.2 uF TIME capacitor). GPIO23 is connected to the LTC1733 PROG pin and is high by default (which puts chip into shutdown mode). Charging cycle starts when GPIO23 is tristated. GPIO15 set charging current limit - low = 100mA, high = (The biggest reading I saw on multimeter was 180mA). End of charging condition is signaled by pulling high GPIO30. Error condition is signaled on GPIO9 pin.

Key reading

5249 ADC is used. Input1 is for internal buttons, and Input0 probably for remote. Below are values taken from dissasembly and crosschecked with "Test mode". The bitflag describes return value of the "read_keys()" subroutine in OF. One can see that flags for internal keys are in low word and for remote are in high word.

ADC1 values

internal key

bitflag

200-500

REC

0x00000020

550-850

VOL-

0x00000010

900-1200

VOL+

0x00000008

1250-1550

NEXT

0x00000002

1600-1900

PREV

0x00000004

1950-2250

SELECT

0x00002000

ADC0 values

remote key

bitflag

230-370

VOL-

0x00100000

480-620

VOL+

0x00080000

830-970

NEXT

0x00020000

1230-1370

PREV

0x00040000

1930-2070

SELECT

0x80000000

44

HOLD

?

In the same routine GPIO56 high produces flag 0x00000001 and GPIO41 produces flag 0x00010000 which is PLAY signal (main and remote respectively).

battery level reading

ADC2 is related to battery level. In firmware there are some flags assigned based on reading from ADC. ADC is read 20 times, than we take mean value of 10 biggest readings and based on this battery level is determined. In other battery related subroutine moving average filter with 20 readings window and ramping is used. Voltages ware measured by hooking external power supply to the connector instead of the battery. Current draw is 70-80 mA for idle and 120-160 mA when playing music. Backlight contribution is about 20mA.

ADC2 values

flag

voltage [V]

<2250

low battery

<3.70

2250-2280

6

3.70 - 3.75

2280-2330

5

3.75 - 3.85

2330-2450

4

3.85 - 4.05

>2450

3

>4.05

Charger connected

1

-

USB sequence

This GPIO toggling sequence is present in a few subroutines in OF related to USB handling:

Enable USB brdge

Disable USB bridge

GPO 50 high

GPO22 high

GPO30 low

GPO30 high

GPO36 low

GPO36 low

delay 10ms

GPO22 high

GPO36 high

GPO50 high

GPO50 low

GPO19 high

GPO22 low

running code

Today (13.11.2009) i fired up my first few lines of code on this device. This was simple 'Hello world'. I injected assembled code into TEST mode subroutines. I poked around and found out unfortunately that unicode.sys which is loaded on coldstart to 0x30E00000 is not preserved there or is not there yet (at least when entering TEST mode). This leaves only few kB of safe code space in TEST mode subroutines to inject my own code.

Debug port

There is unpopulated ZIF/FPC 20-pin connector between battery connector and headphones connector. It is probably BDM port. Here I will try to document my attempt to find proper wiring:

Pins

Function

Notes

3,8,17

GND

mulitmeter

6, 19

VCCIO

multimeter

4

/RESET

multimeter - hardware reset switch pulls this line down

12,11,10,9

PST[0:3]

osciloscope

16,15,14,13

DDATA[0:3]

run program which generate square wave on this pins and look with scope

18

PSTCLK

osciloscope

1

/BKPT

tested

2

DSCLK

tested

5

DSI

tested

7

DSO

tested

20

TA

last one left

By trials I mean put CPU in HALT mode and than setup transmission for GO command and change lines until processor leaves HALT mode. In theory this should work.

edit: 13.01.2010 This works :-). I am able to HALT cpu and resume it. This is BIG step forward because this makes messing with bootloader quite safe.

edit: 19.02.2010 I finaly got PCB for tblcf pod. Thanks to the http://bdm.sourceforge.net I was able to combine BDM and gdb together. Now I have to gain some more practice with gdb.

Tools

hd200icon is small and dirty utility to examine HD200ICON?.sys file. It displays graphics stored insied the file (using SDL), prints offset to the stdout and optionaly can save 'screenshot' of hd200 graphic. Fullscreen frames extracted with this utility are collected in hd200_icons.zip

binpatch small utility to insert binary inside another binary at specified offset. Now obsoleted by mkmpioboot which automates patching firmware file

flash2dram is utility which prints mappings flash<->dram/iram. It is handy in dissasembly to see where particular function from flash is loaded into ram.