This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
AMD flash driver problem - error reading device ID
- From: Uwe Kindler <uwe_kindler at web dot de>
- To: ecos-discuss at sourceware dot org
- Date: Sun, 18 Nov 2007 13:15:23 +0100
- Subject: [ECOS] AMD flash driver problem - error reading device ID
Hello,
currently I'm trying to create a flash driver for our ARM based board.
The flash driver uses the generic AMD v1 driver package
(packages/devs/flash/amd/am29xxxxx).
This is the platform definition of my flash driver:
#define CYGNUM_FLASH_INTERLEAVE (2)
#define CYGNUM_FLASH_WIDTH (16)
#define CYGNUM_FLASH_SERIES (1)
#define CYGNUM_FLASH_BASE (0x80000000u)
The driver fails reading the device ID from the flash device. I tracked
the problem down to the function flash_query() in flash_am29xxxxx.inl.
According to the data sheet of the flash, the sequence for reading the
device ID is:
writing 0xAA to 0x555
writing 0x55 to 0x2AA
writing 0x90 to 0x555
This sequence is represented by the following code in flash_query()
*f_s1 = FLASH_Setup_Code1;
*f_s2 = FLASH_Setup_Code2;
*f_s1 = FLASH_Read_ID;
The problem is, that the calculation of *f_s1 and *f_s2 goes wrong. This
is the code for calculation in flash_query():
ROM = (flash_data_t*) CYGNUM_FLASH_BASE;
f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1);
f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2);
According to my platform definitions I would expect the following values
for the 3 pointers:
ROM = 0x80000000
f_s1 = 0x80000555
f_s2 = 0x800002AA
but after calculation the values are:
ROM = 0x80000000
f_s1 = 0x80001554
f_s2 = 0x80000AA8
I checked the values CYGNUM_FLASH_BASE, FLASH_Setup_Addr1 and
FLASH_Setup_Addr2 with diag_printf(). They have the follwing values:
CYGNUM_FLASH_BASE = 0x80000000
FLASH_Setup_Addr1 = 0x555
FLASH_Setup_Addr2 = 0xAA8
So it seems that the calculation of the pointers goes wrong.
This is the ARM code produced by the 3 lines of code (compiler option -g2):
mov r3, #-2147483648 ; 0x80000000
str r3, [r11, #-20]
ldr r3, [r11, #-20]
add r3, r3, #5440 ; 0x1540
add r3, r3, #20 ; 0x14
str r3, [r11, #-24]
ldr r3, [r11, #-20]
add r3, r3, #2720 ; 0xaa0
add r3, r3, #8 ; 0x8
str r3, [r11, #-28]
I changed the code of the pointer calculation the follwoing way:
ROM = (flash_data_t*) CYGNUM_FLASH_BASE;
f_s1 = FLASH_P2V((cyg_uint32)ROM+FLASH_Setup_Addr1);
f_s2 = FLASH_P2V((cyg_uint32)ROM+FLASH_Setup_Addr2);
Now I get the expected values. The result is:
ROM = 0x80000000
f_s1 = 0x80000555
f_s2 = 0x800002AA
And this is the ARM code produced by the new function:
mov r3, #-2147483648 ; 0x80000000
str r3, [r11, #-20]
ldr r3, [r11, #-20]
add r3, r3, #1360 ; 0x550
add r3, r3, #5 ; 0x5
str r3, [r11, #-24]
ldr r3, [r11, #-20]
add r3, r3, #680 ; 0x2a8
add r3, r3, #2 ; 0x2
str r3, [r11, #-28]
ldr r2, [r11, #-24]
Does someone know what is going wrong here? Normally the code in
flash_query() is used by different ARM platforms so I would not expect a
problem there. I use the ARM toolchain from the eCos hompage so I would
not expect a toolchain problem. Is my code change right and should I
provide a patch or did I something wrong?
Thank you for any help.
Best wishes,
Uwe
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss