X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fat91sam4.c;h=c89c50239c249390cc94e8f5ac639542bb11702a;hp=c5b31e964208d996c30b7bbd2da58a56f2dfd238;hb=b61e454869c988e7fafc1c16982ccfec04415b51;hpb=c4c14d614bfa6f02e8802ebb3f71fcafa729a335;ds=sidebyside diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index c5b31e9642..c89c50239c 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -103,7 +103,7 @@ #define offset_EFC_FSR 8 #define offset_EFC_FRR 12 -extern struct flash_driver at91sam4_flash; +extern const struct flash_driver at91sam4_flash; static float _tomhz(uint32_t freq_hz) { @@ -2376,6 +2376,11 @@ static int sam4_GetInfo(struct sam4_chip *pChip) { const struct sam4_reg_list *pReg; uint32_t regval; + int r; + + r = sam4_ReadAllRegs(pChip); + if (r != ERROR_OK) + return r; pReg = &(sam4_all_regs[0]); while (pReg->name) { @@ -2545,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 */ @@ -2581,14 +2586,35 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate) return ERROR_OK; } -static int _sam4_probe(struct flash_bank *bank, int noise) +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 " TARGET_ADDR_FMT, + pPrivate->pChip->details.name, + pPrivate->bank_number, + k, + bank->base); + + return ERROR_OK; +} + +static int sam4_probe(struct flash_bank *bank) { unsigned x; int r; struct sam4_bank_private *pPrivate; - LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise); + LOG_DEBUG("Begin: Bank: %d", bank->bank_number); if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; @@ -2616,7 +2642,9 @@ static int _sam4_probe(struct flash_bank *bank, int noise) 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 " TARGET_ADDR_FMT " - " + TARGET_ADDR_FMT ", idx %d", bank->base, + bank->base + bank->size, x); break; } } @@ -2655,14 +2683,15 @@ static int _sam4_probe(struct flash_bank *bank, int noise) return r; } -static int sam4_probe(struct flash_bank *bank) -{ - return _sam4_probe(bank, 1); -} - static int sam4_auto_probe(struct flash_bank *bank) { - return _sam4_probe(bank, 0); + struct sam4_bank_private *pPrivate; + + pPrivate = get_sam4_bank_private(bank); + if (pPrivate && pPrivate->probed) + return ERROR_OK; + + return sam4_probe(bank); } static int sam4_erase(struct flash_bank *bank, int first, int last) @@ -2762,20 +2791,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; @@ -2786,7 +2812,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*/ @@ -2874,6 +2912,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; @@ -3091,7 +3133,8 @@ showall: } if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) { r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v); - command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v); + if (r == ERROR_OK) + command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v); return r; } else { command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who); @@ -3169,6 +3212,7 @@ static const struct command_registration at91sam4_exec_command_handlers[] = { .mode = COMMAND_EXEC, .help = "Print information about the current at91sam4 chip" "and its flash configuration.", + .usage = "", }, { .name = "slowclk", @@ -3191,7 +3235,7 @@ static const struct command_registration at91sam4_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct flash_driver at91sam4_flash = { +const struct flash_driver at91sam4_flash = { .name = "at91sam4", .commands = at91sam4_command_handlers, .flash_bank_command = sam4_flash_bank_command, @@ -3203,5 +3247,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, };