According to p.82 of the datasheet, the erase region information
for the S29NS512P is configured as follows (16 bit addresses):

Address     Data      Description
2Dh         0x01FFh   Number of sectors (lower byte)
2Eh         0x0000h   Number of sectors (upper byte)
2Fh         0x0000h   Density of bytes (lower byte)
30h         0x0002h   Density of bytes (upper byte)

However, as stated by CFI standard one should expect that
the Number of sectors, which in this NOR spans more than 8 bits,
should be splitted as follows

Address     Data     Description
2Dh         0x00FFh  Number of sectors (lower byte)
2Eh         0x0001h  Number of sectors (upper byte)

To address this special behavior of 29NS512P I've prepared
the following RFC which has been tested in a Zylin ZY1000
attached to a DM3730 custom board.

Are there any other NOR flash which behave like this one
regarding number of sectors? We've worked with a S29WS512P
in the past but it just does as CFI requires.

[1] http://www.spansion.com/Support/Datasheets/S29NS-P.pdf

Signed-off-by: Javier Martin <[email protected]>
---
 src/flash/nor/cfi.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 3f1fbab..0eda183 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -265,12 +265,37 @@ static int cfi_query_u32(struct flash_bank *bank, int 
sector, uint32_t offset, u
                        return retval;
        }
 
-       if (bank->target->endianness == TARGET_LITTLE_ENDIAN)
-               *val = data[0] | data[bank->bus_width] << 8 |
+       if (bank->target->endianness == TARGET_LITTLE_ENDIAN) {
+               /* Spansion S29N-P doesn't honour CFI standard regarding Erase 
Region Information.
+                * It returns number of sectors in the same 16bit access of 
address 0x2D, */
+               if ((cfi_info->manufacturer == 0x0001) && (cfi_info->device_id 
== 0x307e) &&
+                   bank->bus_width == 2) {
+                       *val = data[0] | data[1] << 8 | data[bank->bus_width * 
2] << 16 |
+                               data[bank->bus_width * 3] << 24;
+               } else {
+                       *val = data[0] | data[bank->bus_width] << 8 |
                                data[bank->bus_width * 2] << 16 | 
data[bank->bus_width * 3] << 24;
-       else
+               }
+       } else {
+               *val = data[bank->bus_width - 1] | data[(2* bank->bus_width) - 
1] << 8 |
+                               data[(3 * bank->bus_width) - 1] << 16 | data[(4 
* bank->bus_width) - 1] << 24;
+       }
+
+       if (bank->target->endianness == TARGET_LITTLE_ENDIAN) {
+               /* Spansion S29N-P doesn't honour CFI standard regarding Erase 
Region Information.
+                * It returns number of sectors in the same 16bit access of 
address 0x2D, */
+               if ((cfi_info->manufacturer == 0x0001) && (cfi_info->device_id 
== 0x307e) &&
+                   bank->bus_width == 2) {
+                       *val = data[0] | data[1] << 8 | data[bank->bus_width * 
2] << 16 |
+                               data[bank->bus_width * 3] << 24;
+               } else {
+                       *val = data[0] | data[bank->bus_width] << 8 |
+                               data[bank->bus_width * 2] << 16 | 
data[bank->bus_width * 3] << 24;
+               }
+       } else {
                *val = data[bank->bus_width - 1] | data[(2* bank->bus_width) - 
1] << 8 |
                                data[(3 * bank->bus_width) - 1] << 16 | data[(4 
* bank->bus_width) - 1] << 24;
+       }
 
        return ERROR_OK;
 }
-- 
1.7.0.4


------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here 
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to