#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)
{
{
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) {
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 */
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;
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;
}
}
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)
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;
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*/
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;
}
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);
.mode = COMMAND_EXEC,
.help = "Print information about the current at91sam4 chip"
"and its flash configuration.",
+ .usage = "",
},
{
.name = "slowclk",
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,
.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,
};