flash/at91sam4: set wait states only once per write
[openocd.git] / src / flash / nor / fm4.c
index 917ff0186b809ba59a5486131911ebbccba68e48..f5eab9c5b39c39444f08de3956344213bd4e1b8b 100644 (file)
@@ -3,8 +3,10 @@
  *
  * Copyright (c) 2015 Andreas Färber
  *
+ * Based on S6E2DH_MN709-00013 for S6E2DH/DF/D5/D3 series
  * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series
  * Based on MB9B560R_MN709-00005 for MB9BFx66/x67/x68 series
+ * Based on MB9B560L_MN709-00006 for MB9BFx64/x65/x66 series
  */
 
 #ifdef HAVE_CONFIG_H
@@ -26,6 +28,8 @@
 #define WDG_LCK (WDG_BASE + 0xC00)
 
 enum fm4_variant {
+       mb9bfx64,
+       mb9bfx65,
        mb9bfx66,
        mb9bfx67,
        mb9bfx68,
@@ -33,6 +37,8 @@ enum fm4_variant {
        s6e2cx8,
        s6e2cx9,
        s6e2cxa,
+
+       s6e2dx,
 };
 
 struct fm4_flash_bank {
@@ -266,7 +272,7 @@ static int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer,
                uint32_t halfwords = MIN(halfword_count, data_workarea->size / 2);
                uint32_t addr = bank->base + offset;
 
-               LOG_DEBUG("copying %" PRId32 " bytes to SRAM 0x%08" PRIx32,
+               LOG_DEBUG("copying %" PRId32 " bytes to SRAM 0x%08" TARGET_PRIxADDR,
                        MIN(halfwords * 2, byte_count), data_workarea->address);
 
                retval = target_write_buffer(target, data_workarea->address,
@@ -342,6 +348,12 @@ static int mb9bf_probe(struct flash_bank *bank)
        int i;
 
        switch (fm4_bank->variant) {
+       case mb9bfx64:
+               bank->num_sectors = 8;
+               break;
+       case mb9bfx65:
+               bank->num_sectors = 10;
+               break;
        case mb9bfx66:
                bank->num_sectors = 12;
                break;
@@ -449,6 +461,32 @@ static int s6e2cc_probe(struct flash_bank *bank)
        return ERROR_OK;
 }
 
+static int s6e2dh_probe(struct flash_bank *bank)
+{
+       uint32_t flash_addr = bank->base;
+       int i;
+
+       bank->num_sectors = 10;
+       bank->sectors = calloc(bank->num_sectors,
+                               sizeof(struct flash_sector));
+       for (i = 0; i < bank->num_sectors; i++) {
+               if (i < 4)
+                       bank->sectors[i].size = 8 * 1024;
+               else if (i == 4)
+                       bank->sectors[i].size = 32 * 1024;
+               else
+                       bank->sectors[i].size = 64 * 1024;
+               bank->sectors[i].offset = flash_addr - bank->base;
+               bank->sectors[i].is_erased = -1;
+               bank->sectors[i].is_protected = -1;
+
+               bank->size += bank->sectors[i].size;
+               flash_addr += bank->sectors[i].size;
+       }
+
+       return ERROR_OK;
+}
+
 static int fm4_probe(struct flash_bank *bank)
 {
        struct fm4_flash_bank *fm4_bank = bank->driver_priv;
@@ -463,6 +501,8 @@ static int fm4_probe(struct flash_bank *bank)
        }
 
        switch (fm4_bank->variant) {
+       case mb9bfx64:
+       case mb9bfx65:
        case mb9bfx66:
        case mb9bfx67:
        case mb9bfx68:
@@ -473,6 +513,9 @@ static int fm4_probe(struct flash_bank *bank)
        case s6e2cxa:
                retval = s6e2cc_probe(bank);
                break;
+       case s6e2dx:
+               retval = s6e2dh_probe(bank);
+               break;
        default:
                return ERROR_FLASH_OPER_UNSUPPORTED;
        }
@@ -510,6 +553,12 @@ static int fm4_get_info_command(struct flash_bank *bank, char *buf, int buf_size
        }
 
        switch (fm4_bank->variant) {
+       case mb9bfx64:
+               name = "MB9BFx64";
+               break;
+       case mb9bfx65:
+               name = "MB9BFx65";
+               break;
        case mb9bfx66:
                name = "MB9BFx66";
                break;
@@ -528,6 +577,9 @@ static int fm4_get_info_command(struct flash_bank *bank, char *buf, int buf_size
        case s6e2cxa:
                name = "S6E2CxA";
                break;
+       case s6e2dx:
+               name = "S6E2Dx";
+               break;
        default:
                name = "unknown";
                break;
@@ -568,7 +620,11 @@ static int mb9bf_bank_setup(struct flash_bank *bank, const char *variant)
 {
        struct fm4_flash_bank *fm4_bank = bank->driver_priv;
 
-       if (fm4_name_match(variant, "MB9BFx66")) {
+       if (fm4_name_match(variant, "MB9BFx64")) {
+               fm4_bank->variant = mb9bfx64;
+       } else if (fm4_name_match(variant, "MB9BFx65")) {
+               fm4_bank->variant = mb9bfx65;
+       } else if (fm4_name_match(variant, "MB9BFx66")) {
                fm4_bank->variant = mb9bfx66;
        } else if (fm4_name_match(variant, "MB9BFx67")) {
                fm4_bank->variant = mb9bfx67;
@@ -624,7 +680,10 @@ FLASH_BANK_COMMAND_HANDLER(fm4_flash_bank_command)
                ret = mb9bf_bank_setup(bank, variant);
        else if (fm4_name_match(variant, "S6E2Cx"))
                ret = s6e2cc_bank_setup(bank, variant);
-       else {
+       else if (fm4_name_match(variant, "S6E2Dx")) {
+               fm4_bank->variant = s6e2dx;
+               ret = ERROR_OK;
+       } else {
                LOG_WARNING("Family %s not recognized.", variant);
                ret = ERROR_FLASH_OPER_UNSUPPORTED;
        }
@@ -656,7 +715,9 @@ struct flash_driver fm4_flash = {
        .probe = fm4_probe,
        .auto_probe = fm4_auto_probe,
        .protect_check = fm4_protect_check,
+       .read = default_flash_read,
        .erase = fm4_flash_erase,
        .erase_check = default_flash_blank_check,
        .write = fm4_flash_write,
+       .free_driver_priv = default_flash_free_driver_priv,
 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)