It was rmini who had the AMD chip, BTW -- I have the ST Micro. But yeah, as far as we can tell, the two chips should be treated identically.
I'd really like to play more with this myself, but I'm juggling daggers right now over here
so let me see if I can at least provide some insightful commentary.
I believe the device should be in 16-bit mode, so the chip id code should be 555, 2AA, 555 according to the datasheet ... that works out to
0101 0101 0101
0010 1010 1010
0101 0101 0101
You said you sent 0x5555, 0x2AAA, 0x5555? that's
0101 0101 0101 0101
0010 1010 1010 1010
0101 0101 0101 0101
Now, the datasheet says that it only looks at A0-A10 for the command interface (so, the rightmost 11 bits)
so it would see
x101 0101 0101
x010 1010 1010
x101 0101 0101
You also said that AAA, 555, AAA shifted left by 1 bit worked, so that's
1010 1010 1010 -> 0101 0101 0100
0101 0101 0101 -> 1010 1010 1010
1010 1010 1010 -> 0101 0101 0100
Soo... that kinda looks like A2 of the processor is connected to A0 of the flash rom -- ie it's throwing away the right two bits of the address. interesting.
That would explain why the chip id bytes are at 0x00 and 0x04 -- because those become 0x00 and 0x01 when you shift them right by 2. They are also at 0x02 and 0x06 because those also turn into 0x00 and 0x04.
(Apologies if this was already obvious -- I'm just trying to reason this out for myself.)
It would seem like the processor would not like that and that you would see stuff doubled in memory when you tried (or it tried) to read the rom to boot off it, or whatever, but I must not be understanding the way the processor handles 16-bit accesses.
So, in theory, if one wanted to erase the last block, #6 (64k from 0x18000 to 0x1ffff), you would do something like
unsigned short *flash_base; // should be 16 bit wide
flash_base=mmap(blah blah blah);
#define WRITE_FLASH(x,y) flash_base[(x)<<1]=y // only shift by 1 because we're doing 16 bits at a time
WRITE_FLASH(0x555,0xAA);
WRITE_FLASH(0x2AA,0x55);
WRITE_FLASH(0x555,0x80);
WRITE_FLASH(0x555,0xAA);
WRITE_FLASH(0x2AA,0x55);
WRITE_FLASH(0x1FFFF,0x30); // this can be any address inside the block
And then 50 ns later it would perform that erase operation.
writing a single 16-bit word would be:
WRITE_FLASH(0x555,0xAA);
WRITE_FLASH(0x2AA,0x55);
WRITE_FLASH(0x555,0xA0);
WRITE_FLASH(address,(16-bits of data));
You might be able to read the protection status of the blocks by doing the same sequence as you'd use for reading the id of the chip, but instead of reading 0x00 or 0x04, you might read (0x0002, 0x1002, 0x2002, 0x3002) << 2 -- and i think those should show up as 0 for unprotected blocks and 1 for protected blocks.
That having been said ... if you managed to erase your chip, that should mean it's unprotected :/
-b