ilyakurdyukov / fpdoom

Doom for feature phones
The Unlicense
63 stars 6 forks source link

Samsung GT-E1272 `LIBUSB_ERROR_PIPE` #8

Closed gohoski closed 1 week ago

gohoski commented 3 months ago

This error happens with the run.bat script from the libc_server release

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723100 bytes
scan_firmware: 461ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
usb_recv failed : LIBUSB_ERROR_PIPE

When running that script again, another error raises:

libusb_get_config_descriptor failed : LIBUSB_ERROR_NOT_FOUND
ilyakurdyukov commented 3 months ago

It's an old SC6530 chip, the oldest I could find was an SC6530C from another old Samsung phone (B310E). So I can't support this as the original SC6530 is very hard to find these days.

ilyakurdyukov commented 3 months ago

But I found it on sale, so I'll write later when I receive it.

ilyakurdyukov commented 3 months ago

When running that script again, another error raises:

libusb_get_config_descriptor failed : LIBUSB_ERROR_NOT_FOUND

If you want to run the script again, then you need to turn off the phone (since it is hang somewhere) by removing the battery and disconnecting it from the USB cable. So the second error is normal under the circumstances.

ilyakurdyukov commented 3 months ago

I received the GT-E1272, but it uses the new SC6531E (aka 6562) chip. It looks like this model was produced with different versions of the chip. So try to dump the firmware from yours, and I’ll try to see the differences.

./spd_dump --wait 300  \
    fdl nor_fdl1.bin 0x40004000 \
    read_mem 0 128K bootloader.bin \
    read_flash 0x80000003 0 4M dump.bin
gohoski commented 3 months ago

Ok, here's the firmware. e1272.zip

gohoski commented 3 months ago

I saw from the new readme that the boot key for your E1272 is 2, while for my E1272 its the OK (center) button. Many tutorials for this phone instruct to press the OK button, so there is definitely some kind of "new version" of this piece of plastic device.

ilyakurdyukov commented 3 months ago

The bootloader is the same size as the SC6530С (0xdb48). The flash is actually larger than 4MB, probably 8MB. But the most important code is in the first part. I think the problem might be the weird RAM size (like 3MB or 6MB), I'll make a custom build of Doom with more prints to make it clearer where the error occurs.

I saw from the new readme that the boot key for your E1272 is 2, while for my E1272 its the OK (center) button. Many tutorials for this phone instruct to press the OK button, so there is definitely some kind of "new version" of this ~piece of plastic~ device.

Since it is on a newer chip, everything may be different, the firmware is incompatible. The boot key is simply the key in the first column and first row. Where the rows and columns are the tracks on the printed circuit board. Perhaps I bought a fake E1272.

Here is a video of the phone that I got.

gohoski commented 3 months ago

Here is a video of the phone that I got.

Your keypad looks a little bit different than mine. Look closely to the voicemail (1), mute (*) and change SIM card (#) buttons. The English font on the keypad looks different too, you either have actually gotten a fake one or Samsung decided to also modify the keypad (or it's a "restored" phone with an unoriginal keypad, which is unlikely).

If you need it, the full compatible with my phone (I have flashed it) firmware is available here.

ilyakurdyukov commented 3 months ago

Yes, the D-pad looks better on your phone. On the one I have, it's difficult to hit the directional buttons.

ilyakurdyukov commented 3 months ago

Try to run Doom from fpdoom_prints.zip from the Releases.

Here's what it should print normally:

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65620001\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 315ms
keymap = 0x10084b10
pinmap = 0x10080eec
chip_id: num = 0x65620001
chip_id: ver = 0xa0002
chip_id: ahb = 0x609
chip_id: adi = 0x1161a000
pin_init
lcm_init
lcm_init 1
lcm_init 2
lcm_init 3
lcm_init 4
LCD: clk_rate = 104000000
LCD: id = 0x009306
lcd_init
lcd_appinit
lcdc_init
keypad_init
keytrn_init
sys_init end
!!! entry2
DOOM Shareware Startup - v1.10

Since there is no "LCD: clk_rate = " in your log, the error is somewhere in the pin_init or lcm_init, so it's not a RAM size issue.

gohoski commented 3 months ago

Here are the logs:

Waiting for connection (300s)
BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 461ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
pin_init
lcm_init
lcm_init 1
lcm_init 2
lcm_init 3
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

So this is a mysterious part, that I copied it from the original firmware:

    if (!is_whtled_on()) lcm_wait(32, 0);

It must be a soft reset of the LCM (LCD Manager).

The LCD detection doesn't work if I disable this line:

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65620001\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 306ms
keymap = 0x10084b10
pinmap = 0x10080eec
chip_id: num = 0x65620001
chip_id: ver = 0xa0002
chip_id: ahb = 0x609
chip_id: adi = 0x1161a000
pin_init
lcm_init
lcm_init 1
lcm_init 2
lcm_init 3
lcm_init 4
LCD: clk_rate = 104000000
LCD: id = 0x040404
!!! unknown LCD
!!! exit(1)

Doesn't work even if I put a 5 second sleep here. I added fpdoom_prints2.zip for you to test, but I don't think it will help you.

I'll try to find this part in your phone's firmware to see if there are any differences.

gohoski commented 3 months ago

Same error as yours, just different ids.

Waiting for connection (300s)
BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 462ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
pin_init
lcm_init
lcm_init 1
lcm_init 2
lcm_init 3
lcm_init 4
LCD: clk_rate = 104000000
LCD: id = 0x008000
!!! unknown LCD
!!! exit(1)
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Now try fpdoom_test1.zip, it looks like is_whtled_on() shouldn't be called for SC6530.

gohoski commented 3 months ago
BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 461ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
_chip = 2
lcm_reset
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

I see, is_whtled_on() is still being called, but it doesn't seem to be causing the hang.

I added fpdoom_test2.zip, but that probably won't help, it appears some necessary initialization is missing.

Or maybe there's not enough power for the LCD.

Try adding the --charger 1 option. Example: cd workdir && ..\libc_server -- --bright 50 --charge 1 --rotate 3 doom

Also try holding down the boot key, insert the battery and connect to USB (hold the boot key until you connect the cable).

gohoski commented 3 months ago

I added fpdoom_test2.zip, but that probably won't help, it appears some necessary initialization is missing.

Or maybe there's not enough power for the LCD.

Try adding the --charger 1 option. Example: cd workdir && ..\libc_server -- --bright 50 --charge 1 --rotate 3 doom

Neither of those things helped :(

Also try holding down the boot key, insert the battery and connect to USB (hold the boot key until you connect the cable).

I actually have been doing that for every time I ran this.

ilyakurdyukov commented 3 months ago

Does this phone boot into its regular OS? Because it's strange that it halts when the LCD is turned on, as if the contacts on the LCD board have shorted out.

gohoski commented 3 months ago

Does this phone boot into its regular OS? Because it's strange that it halts when the LCD is turned on, as if the contacts on the LCD board have shorted out.

Yes it does, by pressing the power key after exiting the download mode.

ilyakurdyukov commented 3 months ago

Does the screen backlight (or flashlight) turn on when running the Doom port?

ilyakurdyukov commented 3 months ago

There seems to be some crazy way to connect a display to an ADC (Analog-to-Digital Converter), that I've never encountered before. Perhaps this method is used in this case. But I can’t do this without a device, it requires a lot of debugging.

ilyakurdyukov commented 3 months ago

Try fpdoom_test3.zip with these settings:

cd workdir && ..\libc_server -- --bright 50 --lcd 0x5cb1f0 --rotate 3 doom

Since the ADC is probably used only for reading from the LCD, we’ll try to do it without detection, this firmware only supports one LCD model.

gohoski commented 3 months ago

Sorry for not replying earlier.

Does the screen backlight (or flashlight) turn on when running the Doom port?

Nope.

Try fpdoom_test3.zip with these settings:

Still the same error...

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 463ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
LCD: clk_rate = 104000000
LCD: id = 0x5cb1f0
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Will adding --gpio_init change anything?

cd workdir && ..\libc_server -- --bright 50 --gpio_init --lcd 0x5cb1f0 --rotate 3 doom
gohoski commented 3 months ago

Will adding --gpio_init change anything?

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 461ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Try fpdoom_test4.zip and I think we'll give up there. You should see "adc_init", "adc_init ok" in the log.

This adds ADC initialization, but I don't think that will help.

static void adc_init(void) {
#if CHIP == 2 || CHIP == 3
    int b = ANA_REG_BASE + 0x680;

    adi_write(ANA_REG_BASE + 0x40, 1);
    adi_write(ANA_REG_BASE + 0x40, 2);
    adi_write(ANA_REG_BASE + 0xe0, 0x20);
    adi_write(ANA_REG_BASE + 0xe0, 0x10);
    adi_write(ANA_REG_BASE + 0xe4, 0x10);
    adi_write(ANA_REG_BASE + 0xa0, 8);
    DELAY(10)
    adi_write(ANA_REG_BASE + 0xb0, 8);

    adi_write(b, adi_read(b) | 1);
    adi_write(b + 0x48, 0xe0);
    adi_write(b + 0x34, adi_read(b + 0x34) | 0x40);
    adi_write(b + 0x2c, adi_read(b + 0x2c) | 0x40);
    adi_write(b + 0x30, adi_read(b + 0x30) | 0x40);
    adi_write(b + 0x28, adi_read(b + 0x28) | 0x40);

    adi_write(b + 0x2c, adi_read(b + 0x2c) & ~0xf);
    adi_write(b + 0x2c, adi_read(b + 0x2c) | 2);
    adi_write(b + 0x34, adi_read(b + 0x34) & ~0xf);
    adi_write(b + 0x34, adi_read(b + 0x34) | 3);
#endif
}
gohoski commented 3 months ago

Try fpdoom_test4.zip and I think we'll give up there. You should see "adc_init", "adc_init ok" in the log.

There is that in the logs, but it still doesn't start. The screen backlight doesn't even turn on…

BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723072 bytes
scan_firmware: 461ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
adc_init
adc_init ok
LCD: clk_rate = 104000000
LCD: id = 0x5cb1f0
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

It could be a watchdog timer, but it's not clear why it suddenly turned on. If you successfully dumped the firmware, it means it was not enabled during dumping.

What OS are you using? Can you rebuild the game binary yourself?

gohoski commented 3 months ago

What OS are you using? Can you rebuild the game binary yourself?

Mostly I use Windows 10, but I have Arch Linux dual-booted.

ilyakurdyukov commented 3 months ago

Try to install ARM cross compiler or Android NDK and compile this.

NDK example:

NDK=$HOME/android-ndk-r25c
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm
CLANG=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang

make all TOOLCHAIN=$TOOLCHAIN CC=$CLANG

cross GCC example:

TOOLCHAIN=/usr/bin/arm-linux-gnueabi

make all TOOLCHAIN="$TOOLCHAIN" LD_EXTRA="-Wl,--no-dynamic-linker"

Use fptest.bin instead of fpdoom.bin, this is a simple display and keypad test.

Put this code in fpdoom/syscode.c to test the timer:

    LCM_CR(0x10) = 1;
    LCM_CR(0x14) = 0xa50100;

+   DBG_LOG("sys_timer = %u\n", sys_timer_ms());
+   sys_wait_ms(1); DBG_LOG("1ms delay ok\n");
+   sys_wait_ms(1000); DBG_LOG("1s delay ok\n");
+   sys_wait_ms(3000); DBG_LOG("3s delay ok\n");

    if (IS_SC6530 || !is_whtled_on()) lcm_reset(32, 0);
ilyakurdyukov commented 3 months ago

Also try doom_test5.zip, I rewrote the SC6530 init code to be similar to later chips.

gohoski commented 3 months ago

Just compiled fptest:

Waiting for connection (300s)
BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 4168308 bytes
scan_firmware: 460ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
sys_timer = 8929
1ms delay ok
usb_recv failed : LIBUSB_ERROR_PIPE

This is what happens with doom_test5:

Waiting for connection (300s)
BSL_REP_VER: "SPRD3\0"
BSL_REP_VER: "Custom FDL1: CHIP ID = 0x65300000\0"
!!! entry1
malloc heap: 3723296 bytes
scan_firmware: 459ms
keymap = 0x300cbf18
pinmap = 0x300cbf98
chip_id: num = 0x65300000
chip_id: ver = 0x90001
chip_id: adi = 0x11300004
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

sys_timer = 8929 1ms delay ok usb_recv failed : LIBUSB_ERROR_PIPE

It looks like watchdog timer is working.

Try putting this before sys_timer check (disables watchdog):

    LCM_CR(0x10) = 1;
    LCM_CR(0x14) = 0xa50100;

+   adi_write(ANA_REG_BASE + 0xa0, 0xe551);
+   DBG_LOG("0x%08x\n", adi_read(ANA_REG_BASE + 0x88));
+   adi_write(ANA_REG_BASE + 0x88, adi_read(ANA_REG_BASE + 0x88) & ~2);
+   adi_write(ANA_REG_BASE + 0xa0, ~0xe551);

    DBG_LOG("sys_timer = %u\n", sys_timer_ms());
    ...

Also try this variant (cuts power to watchdog):

    LCM_CR(0x10) = 1;
    LCM_CR(0x14) = 0xa50100;

+   DBG_LOG("0x%08x 0x%08x\n", adi_read(0x82001120), adi_read(0x82001124));
+   adi_write(0x82001100, 4);
+   adi_write(0x82001104, 2);

    DBG_LOG("sys_timer = %u\n", sys_timer_ms());
    ...
gohoski commented 3 months ago

The first variant prints this:

0x00000000
sys_timer = 3489
1ms delay ok
usb_recv failed : LIBUSB_ERROR_PIPE

And the second variant:

0x00000003 0x00000009
sys_timer = 4028
1ms delay ok
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Watchdog seems to be disabled.

What this will do? It will show how much time we have before the reset.

    LCM_CR(0x10) = 1;
    LCM_CR(0x14) = 0xa50100;

+   uint32_t timer1, timer2 = sys_timer_ms();
+   for (;;) {
+       timer1 = timer2;
+       timer2 = sys_timer_ms();
+       if (timer1 != timer2) DBG_LOG("sys_timer = %u\n", timer2);
+   }
gohoski commented 3 months ago
sys_timer = 3266
sys_timer = 3269
sys_timer = 3273
sys_timer = 3277
sys_timer = 3281
sys_timer = 3285
sys_timer = 3289
sys_timer = 3293
sys_timer = 3297
sys_timer = 3301
sys_timer = 3305
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Try inserting this wait loop somewhere between these calls, will there be a place where it will report the counter forever, without error?

    // here
    init_chip_id();
    // or here
    pin_init();
    // or here
    lcm_init();

The device reboots or hangs after a while. This occurs during LCD init, because it takes some time.

gohoski commented 3 months ago

If I put the loop after init_chip_id , the counter reports for forever, but if I put it after pin_init it hangs after 3639.

ilyakurdyukov commented 3 months ago

There are 150 entries in pinmap. Place this print and sys_wait_ms() in the pin_init loop, it will take 150 seconds to check each entry in the pinmap. The last entry printed before the error should be the one that caused the problem.

 #endif
            MEM4(addr) = val;
        } else break;
+       DBG_LOG("pinmap_trace: 0x%08x, 0x%08x\n", addr, val);
+       sys_wait_ms(1000);
    }
    if (sys_data.gpio_init)
        gpio_init((void*)pinmap);
gohoski commented 3 months ago

It seems that this entry causes the problem:

pinmap_trace: 0x8c000290, 0x00000231
usb_recv failed : LIBUSB_ERROR_PIPE
ilyakurdyukov commented 3 months ago

Filter out the problematic entries, as in this example. There shouldn't be many because this entry is very close to the end of the pinmap.

    for (;;) {
        uint32_t addr = pinmap[0], val = pinmap[1];
        pinmap += 2;
+       if (addr == 0x8c000290) continue;
        if (addr - 0x82001000 < 0x1000) {
            adi_write(addr, val & 0xffff);
        } else if (addr >> 12 == 0x8c000) {
gohoski commented 3 months ago

The screen now just turned on with 4 colours! The terminal also prints out pressed keys, however the numbers seem to be inverted. This is me pressing 123456789*0# on the keypad:

0x37 ("7") press
0x37 ("7") release
0x34 ("4") press
0x34 ("4") release
0x31 ("1") press
0x31 ("1") release
0x38 ("8") press
0x38 ("8") release
0x35 ("5") press
0x35 ("5") release
0x32 ("2") press
0x32 ("2") release
0x39 ("9") press
0x39 ("9") release
0x36 ("6") press
0x36 ("6") release
0x33 ("3") press
0x33 ("3") release
0x2a ("STAR") press
0x2a ("STAR") release
0x30 ("0") press
0x30 ("0") release
0x23 ("HASH") press
0x23 ("HASH") release
ilyakurdyukov commented 3 months ago

This is what the test does if it works. Did you filter only the address 0x8c000290?

gohoski commented 3 months ago

Did you filter only the address 0x8c000290?

Yes

ilyakurdyukov commented 3 months ago

Try doom_test6.zip, I made this fix:

    // ANA_LDO_SF_REG0
    uint32_t ldo_sf0 = adi_read(0x8200148c);
 #endif
+   int sc6530_fix = IS_SC6530 && !sys_data.spi;

    for (;;) {
        uint32_t addr = pinmap[0], val = pinmap[1];
        pinmap += 2;
+       // workaround for Samsung GT-E1272
+       if (sc6530_fix && addr == 0x8c000290) continue;
        if (addr - 0x82001000 < 0x1000) {
            adi_write(addr, val & 0xffff);
        } else if (addr >> 12 == 0x8c000) {

The address seems belongs to SPI, it is safe to skip it if SPI is not used.

gohoski commented 3 months ago

Doom finally runs on this phone, flawlessly and smoothly. I'll record a video of it later.

Thank you for supporting this device.

ilyakurdyukov commented 2 months ago

I added a test for the SDIO subsystem, try rebuilding fptest from the last commit and run it with the SD card inserted. I don't expect failure, just more testing would be helpful.