Menu

#8 JTAG fix to wotk with iPAQ 3600

closed-fixed
jtag (26)
5
2003-02-10
2003-02-08
Alex
No

Hi, I recently had to unbrick an iPAQ 3600 and I
came across your excellent JTAG tools. I used
version 0.2.1 under cygwin under XP.

After countless hours of trying and failing and
picking the brains of the people in the IRC channel
#handhelds.org I finally made the relevant changes
*cough* hacks *cough* to the source to allow it to
flash the FLASH.

The problem is that the iPAQ 3600 I have
implements a sort of flash protection by dropping
VPEN (pin 15) on the flash, therefore the flash
cannot be erased, unlocked or programmed, it can
only be read.

Moreover the VPEN signal is controlled by a 74
type flip/flop (pin 5 of U90 on the pcb). To enable
VPEN (raise it) one must write a 1 to address
0x49000000 so I added a "bus_write( ps,
0x49000000, 1);" to the start of all the flash_*
functions in flash.c however that didn't seem to
work.

After heaps more debugging I traced the problem
to the "sa1110_bus_write' function in sa1110.c

Basically to write to that address nCS5 must go low.
The function above does not seem to use anything
other than nCS0. Additionally, since nCS5
connects to the CLK pin 1 of U90 F/F it gets
latched on the rising edge so it is imperative that
nCS5 is raised again at the end of the bus write.

With those changes to the source, I successfully
programmed the FLASH over JTAG.

Many thanks again for your great program,

Alex

void
sa1110_bus_write( parts *ps, uint32_t adr, uint32_t
data )
{
/* see Figure 10-16 in SA doc */
part *p = ps->parts[0];

if ( (adr==0x49000000) && (data==1) ) {
part_set_signal( p, "nCS0", 1,
1 );
part_set_signal( p, "nCS5", 1,
0 );
} else {
part_set_signal( p, "nCS0", 1,
0 );
part_set_signal( p, "nCS5", 1,
1 );
}
part_set_signal( p, "nCS1", 1, 1 );
part_set_signal( p, "nCS2", 1, 1 );
part_set_signal( p, "nCS3", 1, 1 );
part_set_signal( p, "nCS4", 1, 1 );
part_set_signal( p, "RD_nWR", 1, 0 );
part_set_signal( p, "nWE", 1, 1 );
part_set_signal( p, "nOE", 1, 1 );

setup_address( p, adr );
setup_data( p, data );

parts_shift_data_registers( ps );

part_set_signal( p, "nWE", 1, 0 );
parts_shift_data_registers( ps );
part_set_signal( p, "nWE", 1, 1 );
parts_shift_data_registers( ps );
part_set_signal( p, "nCS0", 1, 1 );
part_set_signal( p, "nCS5", 1, 1 );
parts_shift_data_registers( ps );
}

Discussion

  • Marcel Telka

    Marcel Telka - 2003-02-09
    • status: open --> pending
     
  • Marcel Telka

    Marcel Telka - 2003-02-09
    • status: pending --> pending-postponed
     
  • Marcel Telka

    Marcel Telka - 2003-02-09

    Logged In: YES
    user_id=395402

    nCS1 to nCS5 are not used because access type (ROM bus width
    - RBW) to these memory regions is not automatically
    detectable via JTAG. For nCS0 there is a ROM_SEL...

    But I see that some applications requires more nCS's than
    nCS0 only. Hmmm. I'll add code for support nCSx = 0 setting
    into bus write and bus read functions (thanks for
    suggestion) for SA1110 for all 6 static memory banks.

    It is required to raise nCS5 in separate memory clock at the
    end of the write cycle? What about join this nCS5 raise with
    nWE raising in the previous memclk? It doesn't work for you?
    Memory clocks are very expensive via JTAG :-(.

    Thank you!

     
  • Marcel Telka

    Marcel Telka - 2003-02-10

    Logged In: YES
    user_id=395402

    This is response from d18c7db received by e-mail:

    Yes I verified it earlier today, you can merge the nCSx=1
    and nWE=1 in the same "clock cycle".

     
  • Marcel Telka

    Marcel Telka - 2003-02-10
    • status: pending-postponed --> open-postponed
     
  • Marcel Telka

    Marcel Telka - 2003-02-10

    Logged In: YES
    user_id=395402

    This is now fixed in CVS. Thank you!

     
  • Marcel Telka

    Marcel Telka - 2003-02-10
    • status: open-postponed --> closed-fixed
     

Log in to post a comment.