lpc546xx: Switched to the unified mass erase command for the recovery target and added progress dots to stop GDB timing out
This commit is contained in:
parent
9af2d2a413
commit
8130b62bcf
|
@ -45,7 +45,6 @@
|
||||||
|
|
||||||
#define IAP_PGM_CHUNKSIZE 4096
|
#define IAP_PGM_CHUNKSIZE 4096
|
||||||
|
|
||||||
static bool lpc546xx_cmd_erase_mass(target *t, int argc, const char *argv[]);
|
|
||||||
static bool lpc546xx_cmd_erase_sector(target *t, int argc, const char *argv[]);
|
static bool lpc546xx_cmd_erase_sector(target *t, int argc, const char *argv[]);
|
||||||
static bool lpc546xx_cmd_read_partid(target *t, int argc, const char *argv[]);
|
static bool lpc546xx_cmd_read_partid(target *t, int argc, const char *argv[]);
|
||||||
static bool lpc546xx_cmd_read_uid(target *t, int argc, const char *argv[]);
|
static bool lpc546xx_cmd_read_uid(target *t, int argc, const char *argv[]);
|
||||||
|
@ -56,15 +55,13 @@ static bool lpc546xx_cmd_write_sector(target *t, int argc, const char *argv[]);
|
||||||
static void lpc546xx_reset_attach(target *t);
|
static void lpc546xx_reset_attach(target *t);
|
||||||
static int lpc546xx_flash_init(target *t);
|
static int lpc546xx_flash_init(target *t);
|
||||||
static int lpc546xx_flash_erase(struct target_flash *f, target_addr addr, size_t len);
|
static int lpc546xx_flash_erase(struct target_flash *f, target_addr addr, size_t len);
|
||||||
|
static bool lpc546xx_mass_erase(target *t);
|
||||||
static void lpc546xx_wdt_set_period(target *t);
|
static void lpc546xx_wdt_set_period(target *t);
|
||||||
static void lpc546xx_wdt_pet(target *t);
|
static void lpc546xx_wdt_pet(target *t);
|
||||||
|
|
||||||
const struct command_s lpc546xx_cmd_list[] = {
|
const struct command_s lpc546xx_cmd_list[] = {
|
||||||
{ "erase_mass", lpc546xx_cmd_erase_mass, "Erase entire flash memory" },
|
{ "erase_sector", lpc546xx_cmd_erase_sector, "Erase a sector by number" },
|
||||||
{ "erase_sector", lpc546xx_cmd_erase_sector,
|
{ "read_partid", lpc546xx_cmd_read_partid, "Read out the 32-bit part ID using IAP." },
|
||||||
"Erase a sector by number" },
|
|
||||||
{ "read_partid", lpc546xx_cmd_read_partid,
|
|
||||||
"Read out the 32-bit part ID using IAP." },
|
|
||||||
{ "read_uid", lpc546xx_cmd_read_uid, "Read out the 16-byte UID." },
|
{ "read_uid", lpc546xx_cmd_read_uid, "Read out the 16-byte UID." },
|
||||||
{ "reset_attach", lpc546xx_cmd_reset_attach,
|
{ "reset_attach", lpc546xx_cmd_reset_attach,
|
||||||
"Reset target. Reset debug registers. Re-attach debugger. This restores "
|
"Reset target. Reset debug registers. Re-attach debugger. This restores "
|
||||||
|
@ -153,8 +150,8 @@ bool lpc546xx_probe(target *t)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpc546xx_add_flash(t, IAP_ENTRYPOINT_LOCATION, 0, 0x0, flash_size,
|
t->mass_erase = lpc546xx_mass_erase;
|
||||||
0x8000);
|
lpc546xx_add_flash(t, IAP_ENTRYPOINT_LOCATION, 0, 0x0, flash_size, 0x8000);
|
||||||
|
|
||||||
/* Note: upper 96kB is only usable after enabling the appropriate control
|
/* Note: upper 96kB is only usable after enabling the appropriate control
|
||||||
register bits, see LPC546xx User Manual: 7.5.19 AHB Clock Control register 0
|
register bits, see LPC546xx User Manual: 7.5.19 AHB Clock Control register 0
|
||||||
|
@ -178,22 +175,12 @@ static void lpc546xx_reset_attach(target *t)
|
||||||
cortexm_attach(t);
|
cortexm_attach(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lpc546xx_cmd_erase_mass(target *t, int argc, const char *argv[])
|
static bool lpc546xx_mass_erase(target *t)
|
||||||
{
|
{
|
||||||
(void)argc;
|
const int result = lpc546xx_flash_erase(t->flash, t->flash->start, t->flash->length);
|
||||||
(void)argv;
|
if (result != 0)
|
||||||
|
|
||||||
int result = lpc546xx_flash_erase(t->flash, t->flash->start,
|
|
||||||
t->flash->length);
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
tc_printf(t, "Error erasing flash: %d\n", result);
|
tc_printf(t, "Error erasing flash: %d\n", result);
|
||||||
return false;
|
return result == 0;
|
||||||
}
|
|
||||||
|
|
||||||
tc_printf(t, "Erase OK.\n");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lpc546xx_cmd_erase_sector(target *t, int argc, const char *argv[])
|
static bool lpc546xx_cmd_erase_sector(target *t, int argc, const char *argv[])
|
||||||
|
|
|
@ -93,6 +93,18 @@ struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length)
|
||||||
return lf;
|
return lf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t lpc_sector_for_addr(struct lpc_flash *f, uint32_t addr)
|
||||||
|
{
|
||||||
|
return f->base_sector + (addr - f->f.start) / f->f.blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool lpc_is_full_erase(struct lpc_flash *f, const uint32_t begin, const uint32_t end)
|
||||||
|
{
|
||||||
|
const target_addr addr = f->f.start;
|
||||||
|
const size_t len = f->f.length;
|
||||||
|
return begin == lpc_sector_for_addr(f, addr) && end == lpc_sector_for_addr(f, addr + len - 1U);
|
||||||
|
}
|
||||||
|
|
||||||
enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd, ...)
|
enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd, ...)
|
||||||
{
|
{
|
||||||
target *t = f->f.t;
|
target *t = f->f.t;
|
||||||
|
@ -133,10 +145,15 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd
|
||||||
regs[REG_PC] = f->iap_entry;
|
regs[REG_PC] = f->iap_entry;
|
||||||
target_regs_write(t, regs);
|
target_regs_write(t, regs);
|
||||||
|
|
||||||
|
platform_timeout timeout;
|
||||||
|
platform_timeout_set(&timeout, 500);
|
||||||
|
const bool full_erase = cmd == IAP_CMD_ERASE && lpc_is_full_erase(f, param.words[0], param.words[1]);
|
||||||
/* start the target and wait for it to halt again */
|
/* start the target and wait for it to halt again */
|
||||||
target_halt_resume(t, false);
|
target_halt_resume(t, false);
|
||||||
while (!target_halt_poll(t, NULL))
|
while (!target_halt_poll(t, NULL)) {
|
||||||
continue;
|
if (full_erase)
|
||||||
|
target_print_progress(&timeout);
|
||||||
|
}
|
||||||
|
|
||||||
/* copy back just the parameters structure */
|
/* copy back just the parameters structure */
|
||||||
target_mem_read(t, ¶m, f->iap_ram, sizeof(param));
|
target_mem_read(t, ¶m, f->iap_ram, sizeof(param));
|
||||||
|
@ -163,28 +180,23 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd
|
||||||
return param.status;
|
return param.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t lpc_sector_for_addr(struct lpc_flash *f, uint32_t addr)
|
|
||||||
{
|
|
||||||
return f->base_sector + (addr - f->f.start) / f->f.blocksize;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LPX80X_SECTOR_SIZE 0x400
|
#define LPX80X_SECTOR_SIZE 0x400
|
||||||
#define LPX80X_PAGE_SIZE 0x40
|
#define LPX80X_PAGE_SIZE 0x40
|
||||||
|
|
||||||
int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len)
|
int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len)
|
||||||
{
|
{
|
||||||
struct lpc_flash *f = (struct lpc_flash *)tf;
|
struct lpc_flash *f = (struct lpc_flash *)tf;
|
||||||
uint32_t start = lpc_sector_for_addr(f, addr);
|
const uint32_t start = lpc_sector_for_addr(f, addr);
|
||||||
uint32_t end = lpc_sector_for_addr(f, addr + len - 1);
|
const uint32_t end = lpc_sector_for_addr(f, addr + len - 1U);
|
||||||
uint32_t last_full_sector = end;
|
uint32_t last_full_sector = end;
|
||||||
|
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, start, end, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, start, end, f->bank))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Only LPC80x has reserved pages!*/
|
/* Only LPC80x has reserved pages!*/
|
||||||
if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) {
|
if (f->reserved_pages && addr + len >= tf->length - 0x400U)
|
||||||
last_full_sector -= 1;
|
--last_full_sector;
|
||||||
}
|
|
||||||
if (start <= last_full_sector) {
|
if (start <= last_full_sector) {
|
||||||
/* Sector erase */
|
/* Sector erase */
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank))
|
||||||
|
@ -194,9 +206,11 @@ int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len)
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, last_full_sector, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, last_full_sector, f->bank))
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_full_sector != end) {
|
if (last_full_sector != end) {
|
||||||
uint32_t page_start = (addr + len - LPX80X_SECTOR_SIZE) / LPX80X_PAGE_SIZE;
|
const uint32_t page_start = (addr + len - LPX80X_SECTOR_SIZE) / LPX80X_PAGE_SIZE;
|
||||||
uint32_t page_end = page_start + LPX80X_SECTOR_SIZE/LPX80X_PAGE_SIZE - 1 - f->reserved_pages;
|
const uint32_t page_end = page_start + LPX80X_SECTOR_SIZE / LPX80X_PAGE_SIZE - 1 - f->reserved_pages;
|
||||||
|
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, end, end, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, end, end, f->bank))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue