]> git.sur5r.net Git - openocd/blobdiff - src/flash/nor/at91sam4.c
flash/at91sam4: set wait states only once per write
[openocd] / src / flash / nor / at91sam4.c
index f922c762bcf475b022d85ef940d95740341ce39b..577360a6ee71d4e8267dbc6da58161ad9d670624 100644 (file)
@@ -2550,7 +2550,7 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
                sam4_explain_chipid_cidr(pPrivate->pChip);
                return ERROR_FAIL;
        } else {
-               LOG_INFO("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
+               LOG_DEBUG("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
        }
 
        /* DANGER: THERE ARE DRAGONS HERE */
@@ -2586,6 +2586,27 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
        return ERROR_OK;
 }
 
+static int sam4_info(struct flash_bank *bank, char *buf, int buf_size)
+{
+       struct sam4_bank_private *pPrivate;
+       int k = bank->size / 1024;
+
+       pPrivate = get_sam4_bank_private(bank);
+       if (pPrivate == NULL) {
+               buf[0] = '\0';
+               return ERROR_FAIL;
+       }
+
+       snprintf(buf, buf_size,
+               "%s bank %d: %d kB at 0x%08" PRIx32,
+               pPrivate->pChip->details.name,
+               pPrivate->bank_number,
+               k,
+               bank->base);
+
+       return ERROR_OK;
+}
+
 static int sam4_probe(struct flash_bank *bank)
 {
        unsigned x;
@@ -2621,7 +2642,7 @@ static int sam4_probe(struct flash_bank *bank)
        for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
                if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
                        bank->size = pPrivate->pChip->details.bank[x].size_bytes;
-                       LOG_INFO("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x);
+                       LOG_DEBUG("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x);
                        break;
                }
        }
@@ -2768,20 +2789,17 @@ static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum,
        return r;
 }
 
-static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
+static int sam4_set_wait(struct sam4_bank_private *pPrivate)
 {
-       uint32_t adr;
-       uint32_t status;
        uint32_t fmr;   /* EEFC Flash Mode Register */
        int r;
 
-       adr = pagenum * pPrivate->page_size;
-       adr = (adr + pPrivate->base_address);
-
        /* Get flash mode register value */
        r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
-       if (r != ERROR_OK)
-               LOG_DEBUG("Error Read failed: read flash mode register");
+       if (r != ERROR_OK) {
+               LOG_ERROR("Error Read failed: read flash mode register");
+               return r;
+       }
 
        /* Clear flash wait state field */
        fmr &= 0xfffff0ff;
@@ -2792,7 +2810,19 @@ static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum,
        LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
        r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
        if (r != ERROR_OK)
-               LOG_DEBUG("Error Write failed: set flash mode register");
+               LOG_ERROR("Error Write failed: set flash mode register");
+
+       return r;
+}
+
+static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
+{
+       uint32_t adr;
+       uint32_t status;
+       int r;
+
+       adr = pagenum * pPrivate->page_size;
+       adr = (adr + pPrivate->base_address);
 
        /* 1st sector 8kBytes - page 0 - 15*/
        /* 2nd sector 8kBytes - page 16 - 30*/
@@ -2880,6 +2910,10 @@ static int sam4_write(struct flash_bank *bank,
                goto done;
        }
 
+       r = sam4_set_wait(pPrivate);
+       if (r != ERROR_OK)
+               goto done;
+
        /* what page do we start & end in? */
        page_cur = offset / pPrivate->page_size;
        page_end = (offset + count - 1) / pPrivate->page_size;
@@ -3209,5 +3243,6 @@ struct flash_driver at91sam4_flash = {
        .auto_probe = sam4_auto_probe,
        .erase_check = default_flash_blank_check,
        .protect_check = sam4_protect_check,
+       .info = sam4_info,
        .free_driver_priv = sam4_free_driver_priv,
 };