lpc: Fix bugs related to flash on LPC MCUs

- A previous comment in lpc546xx.c was incorrect - one cannot rely on
resetting the target to leave the main clock set to the 12MHz FRO.
- A comparison in lpc_common.c was incorrect causing flash erase not to
work.
- The IAP API status field was not being explicitly initialized.  If
somehow an API call didn't execute properly (for example if it caused an
exception), we might not notice.  This is fixed by initializing the
status to a value that the API would never return.
This commit is contained in:
Ben Tober 2021-07-22 09:49:38 -04:00 committed by Rachel Mant
parent 16afde7df4
commit 993c74bef4
2 changed files with 14 additions and 2 deletions

View File

@ -40,6 +40,11 @@
#define LPC546XX_WDT_PERIOD_MAX 0xFFFFFF #define LPC546XX_WDT_PERIOD_MAX 0xFFFFFF
#define LPC546XX_WDT_PROTECT (1 << 4) #define LPC546XX_WDT_PROTECT (1 << 4)
#define LPC546XX_MAINCLKSELA 0x40000280
#define LPC546XX_MAINCLKSELB 0x40000284
#define LPC546XX_AHBCLKDIV 0x40000380
#define LPC546XX_FLASHCFG 0x40000400
#define IAP_RAM_SIZE LPC546XX_ETBAHB_SRAM_SIZE #define IAP_RAM_SIZE LPC546XX_ETBAHB_SRAM_SIZE
#define IAP_RAM_BASE LPC546XX_ETBAHB_SRAM_BASE #define IAP_RAM_BASE LPC546XX_ETBAHB_SRAM_BASE
@ -280,13 +285,19 @@ static int lpc546xx_flash_init(target *t)
{ {
/* Reset the chip. It's unfortunate but we need to make sure the ROM /* Reset the chip. It's unfortunate but we need to make sure the ROM
bootloader is no longer mapped to 0x0 or flash blank check won't work after bootloader is no longer mapped to 0x0 or flash blank check won't work after
erasing that sector. Resetting will also set the main clock back to default erasing that sector. Additionally, the ROM itself may increase the
12MHZ FRO; that value is required for some IAP routines. */ main clock frequency during its own operation, so we need to force
it back to the 12MHz FRO to guarantee correct flash timing for
the IAP API */
lpc546xx_reset_attach(t); lpc546xx_reset_attach(t);
/* Deal with WDT */ /* Deal with WDT */
lpc546xx_wdt_set_period(t); lpc546xx_wdt_set_period(t);
target_mem_write32(t, LPC546XX_MAINCLKSELA, 0); // 12MHz FRO
target_mem_write32(t, LPC546XX_MAINCLKSELB, 0); // use MAINCLKSELA
target_mem_write32(t, LPC546XX_AHBCLKDIV, 0); // Divide by 1
target_mem_write32(t, LPC546XX_FLASHCFG, 0x1a); // recommended default
return 0; return 0;
} }

View File

@ -110,6 +110,7 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd
struct flash_param param = { struct flash_param param = {
.opcode = ARM_THUMB_BREAKPOINT, .opcode = ARM_THUMB_BREAKPOINT,
.command = cmd, .command = cmd,
.status = 0xdeadbeef, // to help us see if the IAP didn't execute
}; };
/* Pet WDT before each IAP call, if it is on */ /* Pet WDT before each IAP call, if it is on */