aboutsummaryrefslogtreecommitdiff
path: root/src/lpc43xx.c
diff options
context:
space:
mode:
authorAllen Ibara2014-09-09 15:11:29 -0700
committerAllen Ibara2014-09-16 14:54:24 -0700
commitc5abc9a0bdde15f168903911ea43a6df1c7650ca (patch)
tree1ab45a45553ec16bf0be32dded9190e2359019fc /src/lpc43xx.c
parent091389b982477bb96624b51f59930f304813bca8 (diff)
LPC43XX: Attempt to handle case of running WDT.
If the WDT is running, it may reset while we are trying to flash. Since we can't disable it, we set a long period and attempt to pet it before each IAP call.
Diffstat (limited to 'src/lpc43xx.c')
-rw-r--r--src/lpc43xx.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/lpc43xx.c b/src/lpc43xx.c
index 0376ecf..a739878 100644
--- a/src/lpc43xx.c
+++ b/src/lpc43xx.c
@@ -37,6 +37,12 @@
#define LPC43XX_ETBAHB_SRAM_BASE 0x2000C000
#define LPC43XX_ETBAHB_SRAM_SIZE (16*1024)
+#define LPC43XX_WDT_MODE 0x40080000
+#define LPC43XX_WDT_CNT 0x40080004
+#define LPC43XX_WDT_FEED 0x40080008
+#define LPC43XX_WDT_PERIOD_MAX 0xFFFFFF
+#define LPC43XX_WDT_PROTECT (1 << 4)
+
#define IAP_RAM_SIZE LPC43XX_ETBAHB_SRAM_SIZE
#define IAP_RAM_BASE LPC43XX_ETBAHB_SRAM_BASE
@@ -126,6 +132,8 @@ static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, int len);
static int lpc43xx_flash_write(struct target_s *target,
uint32_t dest, const uint8_t *src, int len);
static void lpc43xx_set_internal_clock(struct target_s *target);
+static void lpc43xx_wdt_set_period(struct target_s *target);
+static void lpc43xx_wdt_pet(struct target_s *target);
const struct command_s lpc43xx_cmd_list[] = {
{"erase_mass", lpc43xx_cmd_erase, "Erase entire flash memory"},
@@ -264,11 +272,14 @@ static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
static int lpc43xx_flash_init(struct target_s *target)
{
- struct flash_program flash_pgm;
+ /* Deal with WDT */
+ lpc43xx_wdt_set_period(target);
/* Force internal clock */
lpc43xx_set_internal_clock(target);
+ struct flash_program flash_pgm;
+
/* Initialize flash IAP */
flash_pgm.p.command = IAP_CMD_INIT;
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
@@ -327,6 +338,9 @@ static void lpc43xx_iap_call(struct target_s *target, struct flash_param *param,
uint32_t regs[target->regs_size / sizeof(uint32_t)];
uint32_t iap_entry;
+ /* Pet WDT before each IAP call, if it is on */
+ lpc43xx_wdt_pet(target);
+
target_mem_read_words(target, &iap_entry, IAP_ENTRYPOINT_LOCATION, sizeof(iap_entry));
/* fill out the remainder of the parameters and copy the structure to RAM */
@@ -524,3 +538,36 @@ static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[])
return true;
}
+static void lpc43xx_wdt_set_period(struct target_s *target)
+{
+ uint32_t wdt_mode = 0;
+ /* Check if WDT is on */
+ target_mem_read_words(target, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
+
+ /* If WDT on, we can't disable it, but we may be able to set a long period */
+ if (wdt_mode && !(wdt_mode & LPC43XX_WDT_PROTECT))
+ {
+ const uint32_t wdt_period = LPC43XX_WDT_PERIOD_MAX;
+
+
+ target_mem_write_words(target, LPC43XX_WDT_CNT, &wdt_period, sizeof(wdt_period));
+ }
+}
+
+static void lpc43xx_wdt_pet(struct target_s *target)
+{
+ uint32_t wdt_mode = 0;
+ /* Check if WDT is on */
+ target_mem_read_words(target, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
+
+ /* If WDT on, pet */
+ if (wdt_mode)
+ {
+ const uint32_t feed1 = 0xAA;;
+ const uint32_t feed2 = 0x55;;
+
+
+ target_mem_write_words(target, LPC43XX_WDT_FEED, &feed1, sizeof(feed1));
+ target_mem_write_words(target, LPC43XX_WDT_FEED, &feed2, sizeof(feed2));
+ }
+}