Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/include/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ bool target_mem_access_needs_halt(target_s *target);
bool target_flash_erase(target_s *target, target_addr_t addr, size_t len);
bool target_flash_write(target_s *target, target_addr_t dest, const void *src, size_t len);
bool target_flash_complete(target_s *target);
bool target_flash_mass_erase(target_s *target);

/* Register access functions */
size_t target_regs_size(target_s *target);
Expand Down
10 changes: 4 additions & 6 deletions src/target/at32f43x.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static bool at32f43_flash_prepare(target_flash_s *flash);
static bool at32f43_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len);
static bool at32f43_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len);
static bool at32f43_flash_done(target_flash_s *flash);
static bool at32f43_mass_erase(target_s *target);
static bool at32f43_mass_erase(target_s *target, platform_timeout_s *print_progess);

/* Flash memory controller register map */
#define AT32F43x_FLASH_REG_BASE 0x40023c00U
Expand Down Expand Up @@ -538,17 +538,15 @@ static bool at32f43_mass_erase_bank(
return at32f43_flash_busy_wait(target, bank_reg_offset, timeout);
}

static bool at32f43_mass_erase(target_s *target)
static bool at32f43_mass_erase(target_s *const target, platform_timeout_s *const print_progess)
{
/* Datasheet: bank erase takes seconds to complete */
platform_timeout_s timeout;
platform_timeout_set(&timeout, 500);
if (!at32f43_mass_erase_bank(target, AT32F43x_FLASH_BANK1_REG_OFFSET, &timeout))
if (!at32f43_mass_erase_bank(target, AT32F43x_FLASH_BANK1_REG_OFFSET, print_progess))
return false;

/* For dual-bank targets, mass erase bank 2 as well */
if (target->flash->next)
return at32f43_mass_erase_bank(target, AT32F43x_FLASH_BANK2_REG_OFFSET, &timeout);
return at32f43_mass_erase_bank(target, AT32F43x_FLASH_BANK2_REG_OFFSET, print_progess);
return true;
}

Expand Down
25 changes: 11 additions & 14 deletions src/target/efm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

static bool efm32_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
static bool efm32_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
static bool efm32_mass_erase(target_s *t);
static bool efm32_mass_erase(target_s *t, platform_timeout_s *print_progess);

static const uint16_t efm32_flash_write_stub[] = {
#include "flashstub/efm32.stub"
Expand Down Expand Up @@ -666,7 +666,7 @@ static bool efm32_flash_write(target_flash_s *f, target_addr_t dest, const void
}

/* Uses the MSC ERASEMAIN0/1 command to erase the entire flash */
static bool efm32_mass_erase(target_s *t)
static bool efm32_mass_erase(target_s *const t, platform_timeout_s *const print_progess)
{
efm32_priv_s *priv_storage = (efm32_priv_s *)t->target_storage;
if (!priv_storage || !priv_storage->device)
Expand All @@ -691,25 +691,23 @@ static bool efm32_mass_erase(target_s *t)
/* Erase operation */
target_mem32_write32(t, EFM32_MSC_WRITECMD(msc), EFM32_MSC_WRITECMD_ERASEMAIN0);

platform_timeout_s timeout;
platform_timeout_set(&timeout, 500);
/* Poll MSC Busy */
while ((target_mem32_read32(t, EFM32_MSC_STATUS(msc)) & EFM32_MSC_STATUS_BUSY)) {
if (target_check_error(t))
return false;
target_print_progress(&timeout);
target_print_progress(print_progess);
}

/* Parts with >= 512 kiB flash have 2 mass erase regions */
if (flash_kib >= 512) {
if (flash_kib >= 512U) {
/* Erase operation */
target_mem32_write32(t, EFM32_MSC_WRITECMD(msc), EFM32_MSC_WRITECMD_ERASEMAIN1);

/* Poll MSC Busy */
while ((target_mem32_read32(t, EFM32_MSC_STATUS(msc)) & EFM32_MSC_STATUS_BUSY)) {
if (target_check_error(t))
return false;
target_print_progress(&timeout);
target_print_progress(print_progess);
}
}

Expand Down Expand Up @@ -926,7 +924,7 @@ static bool efm32_cmd_bootloader(target_s *t, int argc, const char **argv)

#define CMDKEY 0xcfacc118U

static bool efm32_aap_mass_erase(target_s *t);
static bool efm32_aap_mass_erase(target_s *t, platform_timeout_s *print_progess);

/* AAP Probe */
typedef struct efm32_aap_priv {
Expand All @@ -950,6 +948,7 @@ bool efm32_aap_probe(adiv5_access_port_s *ap)
return false;
}

t->enter_flash_mode = target_enter_flash_mode_stub;
t->mass_erase = efm32_aap_mass_erase;

adiv5_ap_ref(ap);
Expand All @@ -968,9 +967,9 @@ bool efm32_aap_probe(adiv5_access_port_s *ap)
return true;
}

static bool efm32_aap_mass_erase(target_s *t)
static bool efm32_aap_mass_erase(target_s *const t, platform_timeout_s *const print_progess)
{
adiv5_access_port_s *ap = t->priv;
adiv5_access_port_s *ap = cortex_ap(t);
uint32_t status;

/* Read status */
Expand All @@ -985,14 +984,12 @@ static bool efm32_aap_mass_erase(target_s *t)

DEBUG_INFO("EFM32: Issuing DEVICEERASE...\n");
adiv5_ap_write(ap, AAP_CMDKEY, CMDKEY);
adiv5_ap_write(ap, AAP_CMD, 1);
adiv5_ap_write(ap, AAP_CMD, 1U);

platform_timeout_s timeout;
platform_timeout_set(&timeout, 500);
/* Read until 0, probably should have a timeout here... */
do {
status = adiv5_ap_read(ap, AAP_STATUS);
target_print_progress(&timeout);
target_print_progress(print_progess);
} while (status & AAP_STATUS_ERASEBUSY);

/* Read status */
Expand Down
42 changes: 21 additions & 21 deletions src/target/hc32l110.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static bool hc32l110_flash_prepare(target_flash_s *flash);
static bool hc32l110_flash_done(target_flash_s *flash);
static bool hc32l110_flash_erase(target_flash_s *flash, target_addr_t addr, size_t length);
static bool hc32l110_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t length);
static bool hc32l110_mass_erase(target_s *target);
static bool hc32l110_mass_erase(target_s *target, platform_timeout_s *print_progess);

static void hc32l110_add_flash(target_s *target, const uint32_t flash_size)
{
Expand Down Expand Up @@ -130,7 +130,8 @@ static void hc32l110_flash_cr_unlock(target_s *const target)
target_mem32_write32(target, HC32L110_FLASH_BYPASS, 0xa5a5U);
}

static bool hc32l110_check_flash_completion(target_s *const target, const uint32_t timeout_ms)
static bool hc32l110_check_flash_completion(
target_s *const target, const uint32_t timeout_ms, platform_timeout_s *const print_progess)
{
platform_timeout_s timeout;
platform_timeout_set(&timeout, timeout_ms);
Expand All @@ -139,6 +140,8 @@ static bool hc32l110_check_flash_completion(target_s *const target, const uint32
status = target_mem32_read32(target, HC32L110_FLASH_CR);
if (target_check_error(target) || platform_timeout_is_expired(&timeout))
return false;
if (print_progess)
target_print_progress(print_progess);
}
return true;
}
Expand Down Expand Up @@ -174,18 +177,26 @@ static bool hc32l110_flash_prepare(target_flash_s *const flash)
{
hc32l110_flash_cr_unlock(flash->t);

uint32_t cr_operation = 0;
switch (flash->operation) {
case FLASH_OPERATION_WRITE:
target_mem32_write32(flash->t, HC32L110_FLASH_CR, HC32L110_FLASH_CR_OP_PROGRAM);
cr_operation = HC32L110_FLASH_CR_OP_PROGRAM;
break;
case FLASH_OPERATION_ERASE:
target_mem32_write32(flash->t, HC32L110_FLASH_CR, HC32L110_FLASH_CR_OP_ERASE_SECTOR);
cr_operation = HC32L110_FLASH_CR_OP_ERASE_SECTOR;
break;
case FLASH_OPERATION_MASS_ERASE:
cr_operation = HC32L110_FLASH_CR_OP_ERASE_CHIP;
break;
default:
DEBUG_WARN("unsupported operation %u", flash->operation);
return false;
}

target_mem32_write32(flash->t, HC32L110_FLASH_CR, cr_operation);
if (!hc32l110_check_flash_completion(flash->t, 500U, NULL))
return false;

hc32l110_slock_unlock_all(flash->t);
return true;
}
Expand All @@ -201,32 +212,21 @@ static bool hc32l110_flash_erase(target_flash_s *const flash, const target_addr_
(void)length;
/* The Flash controller automatically erases the whole sector after one write operation */
target_mem32_write32(flash->t, addr, 0);
return hc32l110_check_flash_completion(flash->t, 1000);
return hc32l110_check_flash_completion(flash->t, 1000, NULL);
}

static bool hc32l110_flash_write(
target_flash_s *const flash, const target_addr_t dest, const void *const src, const size_t length)
{
(void)length;
target_mem32_write32(flash->t, dest, *(const uint32_t *)src);
return hc32l110_check_flash_completion(flash->t, 1000);
return hc32l110_check_flash_completion(flash->t, 1000, NULL);
}

static bool hc32l110_mass_erase(target_s *target)
/* FIXME: looks like this might make sense as a flash->mass erase routine */
static bool hc32l110_mass_erase(target_s *const target, platform_timeout_s *const print_progess)
{
hc32l110_enter_flash_mode(target);

hc32l110_flash_cr_unlock(target);
target_mem32_write32(target, HC32L110_FLASH_CR, HC32L110_FLASH_CR_OP_ERASE_CHIP);
if (!hc32l110_check_flash_completion(target, 500))
return false;

hc32l110_slock_unlock_all(target);

// The Flash controller automatically erases the whole Flash after one write operation
target_mem32_write32(target, 0, 0);
const bool result = hc32l110_check_flash_completion(target, 4000);

hc32l110_slock_lock_all(target);
return result;
target_mem32_write32(target, 0x0U, 0U);
return hc32l110_check_flash_completion(target, 4000U, print_progess);
}
1 change: 0 additions & 1 deletion src/target/imxrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ bool imxrt_probe(target_s *const target)
spi_flash_id_s flash_id;
imxrt_spi_read(target, SPI_FLASH_CMD_READ_JEDEC_ID, 0, &flash_id, sizeof(flash_id));

target->mass_erase = bmp_spi_mass_erase;
target->enter_flash_mode = imxrt_enter_flash_mode;
target->exit_flash_mode = imxrt_exit_flash_mode;

Expand Down
13 changes: 6 additions & 7 deletions src/target/kinetis.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ static bool kinetis_flash_done(target_flash_s *const f)
* device. This provides a fake target to allow a monitor command interface
*/

static bool kinetis_mdm_mass_erase(target_s *t);
static bool kinetis_mdm_mass_erase(target_s *t, platform_timeout_s *const print_progess);
static bool kinetis_mdm_cmd_ke04_mode(target_s *t, int argc, const char **argv);

const command_s kinetis_mdm_cmd_list[] = {
Expand Down Expand Up @@ -569,6 +569,7 @@ bool kinetis_mdm_probe(adiv5_access_port_s *ap)
return false;
}

t->enter_flash_mode = target_enter_flash_mode_stub;
t->mass_erase = kinetis_mdm_mass_erase;
adiv5_ap_ref(ap);
t->priv = ap;
Expand All @@ -593,13 +594,13 @@ static bool kinetis_mdm_cmd_ke04_mode(target_s *t, int argc, const char **argv)
return true;
}

static bool kinetis_mdm_mass_erase(target_s *t)
static bool kinetis_mdm_mass_erase(target_s *const t, platform_timeout_s *const print_progess)
{
adiv5_access_port_s *ap = t->priv;

/* Keep the MCU in reset as stated in KL25PxxM48SF0RM */
if (t->ke04_mode)
adiv5_ap_write(ap, MDM_CONTROL, MDM_CONTROL_SYS_RESET);
adiv5_ap_write(ap, MDM_CONTROL, MDM_CONTROL_SYS_RESET); /* FIXME: move this to enter_flash_mode? */

uint32_t status = adiv5_ap_read(ap, MDM_STATUS);
uint32_t control = adiv5_ap_read(ap, MDM_CONTROL);
Expand All @@ -625,18 +626,16 @@ static bool kinetis_mdm_mass_erase(target_s *t)
}

adiv5_ap_write(ap, MDM_CONTROL, MDM_CONTROL_MASS_ERASE);
platform_timeout_s timeout;
platform_timeout_set(&timeout, 500);

do {
status = adiv5_ap_read(ap, MDM_STATUS);
target_print_progress(&timeout);
target_print_progress(print_progess);
} while (!(status & MDM_STATUS_MASS_ERASE_ACK));
tc_printf(t, "Mass erase acknowledged\n");

do {
control = adiv5_ap_read(ap, MDM_CONTROL);
target_print_progress(&timeout);
target_print_progress(print_progess);
} while (!(control & MDM_CONTROL_MASS_ERASE));
tc_printf(t, "Mass erase complete\n");

Expand Down
8 changes: 0 additions & 8 deletions src/target/lmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@

static bool lmi_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len);
static bool lmi_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len);
static bool lmi_mass_erase(target_s *target);

static const uint16_t lmi_flash_write_stub[] = {
#include "flashstub/lmi.stub"
Expand Down Expand Up @@ -141,7 +140,6 @@ bool lm3s_probe(target_s *const target, const uint16_t did1)
return false;
}
target->driver = "Stellaris";
target->mass_erase = lmi_mass_erase;
return true;
}

Expand Down Expand Up @@ -177,7 +175,6 @@ bool tm4c_probe(target_s *const target, const uint16_t did1)
return false;
}
target->driver = "Tiva-C";
target->mass_erase = lmi_mass_erase;
cortex_ap(target)->dp->quirks |= ADIV5_DP_QUIRK_DUPED_AP;
return true;
}
Expand Down Expand Up @@ -236,8 +233,3 @@ static bool lmi_flash_write(target_flash_s *flash, target_addr_t dest, const voi

return cortexm_run_stub(target, SRAM_BASE, dest, STUB_BUFFER_BASE, len, 0) == 0;
}

static bool lmi_mass_erase(target_s *target)
{
return lmi_flash_erase(target->flash, target->flash->start, target->flash->length);
}
Loading