release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Search | Go
Wiki > Main > IriverPort > FirmwareDisassemblyH300

Disassembly of the iriver H300 original firmware

General

I took the time to start a serious disassembly of the H300 1.30eu iriver firmware to see if I could find out some things about the power management, and the handling of the remote controls.

Progress

I have so far disassembled the boot process up to when the actual firmware code is copied to RAM and started.

Findings so far

Nothing spectacular, but here are a few things that they do and we should:

PCF50606

Some general purpose outputs are set like this when enabling the backlight:
Register Value Meaning Comment
0x39 0x07 GPO0ACT? = 1, GPO1ACT? = 0 I don't yet know what these pins do
0x3a 0x3b GPOOD0ACT? = inv. PWM, GPOOD0STB? = PWM HiZ The backlight pin is tristated when the device is off Will recheck this

Also, when they turn off the device, they set GPOOD2 and GPOOD3 like this:
Register Value Meaning Comment
0x3b 0x00 GPOOD2ACT? = HiZ, GPOOD2STB? = HiZ UDA1380 Reset
0x3c 0x07 GPOOD3ACT? = 0, GPOOD3STB? = HiZ I don't know what this pin does

For some reason, the application retains the OPMOD settings for the regulators:

IOREGC = (IOREGC & 0xe0) | 0x14;
D1REGC = (D1REGC & 0xe0) | 0x1f;
D2REGC = ((D2REGC & 0xe0) | 0x18) & 0x1f; /* What a silly thing to do... */
D3REGC = (D3REGC & 0xe0) | 0x10;
LPREGC = (LPREGC & 0xe0) | 0x0f;

LCD

This is the sequence they seem to use for turning on and off the LCD:

void lcd_enable(bool on_off)
{
   if(on_off)
   {
      lcd_write_reg(R_DISP_CONTROL1, 0x0061);
      sleep(1);
      lcd_write_reg(R_DISP_CONTROL1, 0x0067);
      sleep(1);
      lcd_write_reg(R_DISP_CONTROL1, 0x0637);
      backlight_on();
   }
   else
   {
      backlight_off();
      lcd_write_reg(R_DISP_CONTROL1, 0x0636);
      sleep(1);
      lcd_write_reg(R_DISP_CONTROL1, 0x0626);
   }
}

RTC

Here is the iriver code that sets the RTC:

struct timedata
{
   unsigned char sec;
   unsigned char min;
   unsigned char hour;
   unsigned char wday;
   unsigned char mday;
   unsigned short year;
};

void rtc_set_time(struct timedata *tm)
{
   unsigned char buf[6];

   if(tm->sec > 59)
      tm->sec = 0;

   if(tm->min > 59)
      tm->min = 0;

   if(tm-hour > 23)
      tm->hour = 0;

   if(tm->wday > 6)
      tm->wday = 0;

   if(tm->mday > 31 || tm->mday == 0)
      tm->mday = 1;

   if(tm->mon > 12 || tm->mon == 0)
      tm->mon = 1;

   if(tm->year-1965 > 99)
      tm->year = 1965;

   buf[0] = bcd(tm->sec);
   buf[1] = bcd(tm->min);
   buf[2] = bcd(tm->hour);
   buf[3] = bcd(tm->wday);
   buf[4] = bcd(tm->mday);
   buf[5] = bcd(tm->mon);
   buf[6] = bcd(tm->year-1965);
   
   pcf50606_write(0x0a, 6, buf);
}
r9 - 30 Sep 2007 - 17:56:38 - NicolasPennequin

Parents: IriverPort
Copyright by the contributing authors.