aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/loaders/watchdog/Makefile2
-rw-r--r--contrib/loaders/watchdog/armv7m_kinetis_wdog.inc5
-rw-r--r--contrib/loaders/watchdog/armv7m_kinetis_wdog.s14
-rw-r--r--contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc5
-rw-r--r--contrib/loaders/watchdog/armv7m_kinetis_wdog32.s81
-rw-r--r--src/flash/nor/kinetis.c273
-rw-r--r--tcl/target/klx.cfg16
-rw-r--r--tcl/target/kx.cfg8
8 files changed, 316 insertions, 88 deletions
diff --git a/contrib/loaders/watchdog/Makefile b/contrib/loaders/watchdog/Makefile
index 623e744..ed6d8f4 100644
--- a/contrib/loaders/watchdog/Makefile
+++ b/contrib/loaders/watchdog/Makefile
@@ -6,7 +6,7 @@ ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy
ARM_AFLAGS = -EL -mthumb
-arm: armv7m_kinetis_wdog.inc
+arm: armv7m_kinetis_wdog.inc armv7m_kinetis_wdog32.inc
armv7m_%.elf: armv7m_%.s
$(ARM_AS) $(ARM_AFLAGS) $< -o $@
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
index 4b6579e..317d084 100644
--- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
@@ -1,4 +1,3 @@
/* Autogenerated with ../../../src/helper/bin2char.sh */
-0x04,0x4b,0x05,0x4a,0xda,0x81,0x05,0x4a,0xda,0x81,0x01,0x24,0x1a,0x88,0xa2,0x43,
-0x1a,0x80,0x06,0xe0,0x00,0x20,0x05,0x40,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,
-0x00,0x00,0x00,0xbe,
+0x04,0x4a,0xc2,0x81,0x04,0x4a,0xc2,0x81,0x01,0x24,0x02,0x88,0xa2,0x43,0x02,0x80,
+0x05,0xe0,0x00,0x00,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,0x00,0x00,0x00,0xbe,
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
index bac924a..d724192 100644
--- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
@@ -19,7 +19,9 @@
/*
Disable watchdog for Kinetis Kx and KVx
- Parameters: none
+ Parameters:
+ r0 ... WDOG base (in)
+
Used instruction set should work on both Cortex-M4 and M0+
*/
@@ -28,7 +30,6 @@
.cpu cortex-m0
.thumb
-WDOG_ADDR = 0x40052000
/* WDOG registers offsets */
WDOG_STCTRLH = 0
WDOG_UNLOCK = 0x0e
@@ -39,17 +40,16 @@ WDOG_KEY2 = 0xd928
.thumb_func
start:
/* WDOG_UNLOCK = 0xC520 */
- ldr r3, =WDOG_ADDR
ldr r2, =WDOG_KEY1
- strh r2, [r3, WDOG_UNLOCK]
+ strh r2, [r0, WDOG_UNLOCK]
/* WDOG_UNLOCK = 0xD928 */
ldr r2, =WDOG_KEY2
- strh r2, [r3, WDOG_UNLOCK]
+ strh r2, [r0, WDOG_UNLOCK]
/* WDOG_STCTRLH clear bit 0 */
movs r4, #1
- ldrh r2, [r3, WDOG_STCTRLH]
+ ldrh r2, [r0, WDOG_STCTRLH]
bics r2, r4
- strh r2, [r3, WDOG_STCTRLH]
+ strh r2, [r0, WDOG_STCTRLH]
/* OpenOCD checks exit point address. Jump to the very end. */
b done
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc
new file mode 100644
index 0000000..4ee06ed
--- /dev/null
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc
@@ -0,0 +1,5 @@
+/* Autogenerated with ../../../src/helper/bin2char.sh */
+0x02,0x68,0x08,0x4b,0x1a,0x42,0x08,0x4b,0x01,0xd0,0x43,0x60,0x02,0xe0,0x83,0x80,
+0x1b,0x0c,0x83,0x80,0x80,0x24,0xa2,0x43,0x20,0x24,0x22,0x43,0x02,0x60,0x03,0x4b,
+0x83,0x60,0x06,0xe0,0x00,0x20,0x00,0x00,0x20,0xc5,0x28,0xd9,0x00,0x04,0x00,0x00,
+0x00,0x00,0x00,0xbe,
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s
new file mode 100644
index 0000000..bf58327
--- /dev/null
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * Copyright (C) 2017 Tomas Vanek *
+ * vanekt@fbl.cz *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc. *
+ ***************************************************************************/
+
+/*
+ Disable watchdog, 32-bit version for newer Kinetis
+ Parameters:
+ r0 ... WDOG32 base (in)
+
+ Used instruction set should work on both Cortex-M4 and M0+
+*/
+
+ .text
+ .syntax unified
+ .cpu cortex-m0
+ .thumb
+
+/* WDOG registers offsets */
+WDOG_CS = 0
+WDOG_CNT = 4
+WDOG_TOVAL = 8
+
+WDOG_KEY = 0xd928c520
+
+ .thumb_func
+start:
+/* test WDOG_CS bit CMD32EN */
+ ldr r2, [r0, WDOG_CS]
+ ldr r3, =0x2000
+ tst r2, r3
+ ldr r3, =WDOG_KEY
+ beq cmd16
+
+/* WDOG_CNT = key */
+ str r3, [r0, WDOG_CNT]
+ b unlocked
+
+cmd16:
+/* WDOG_CNT = key, halfword by halfword */
+ strh r3, [r0, WDOG_CNT]
+ lsrs r3, r3, #16
+ strh r3, [r0, WDOG_CNT]
+
+/* WDOG_CS: clear EN bit 7, set UPDATE bit 5 */
+unlocked:
+ movs r4, #0x80
+ bics r2, r4
+ movs r4, #0x20
+ orrs r2, r4
+ str r2, [r0, WDOG_CS]
+/* All active WDOG registers have to be updated, set dummy timeout */
+/* WDOG_TOVAL = 0x400 */
+ ldr r3, =0x400
+ str r3, [r0, WDOG_TOVAL]
+/* OpenOCD checks exit point address. Jump to the very end. */
+ b done
+
+ .pool
+
+/* Avoid padding at .text segment end. Otherwise exit point check fails. */
+ .skip ( . - start + 2) & 2, 0
+done:
+ bkpt #0
+
+ .end
+
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index dc3dc45..1f2383d 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -100,11 +100,18 @@
#define SIM_SOPT1 0x40047000
#define SIM_FCFG1 0x4004804c
#define SIM_FCFG2 0x40048050
-#define WDOG_STCTRH 0x40052000
+#define SIM_COPC 0x40048100
+#define WDOG_BASE 0x40052000
+#define WDOG32_KE1X 0x40052000
+#define WDOG32_KL28 0x40076000
#define SMC_PMCTRL 0x4007E001
#define SMC_PMSTAT 0x4007E003
#define MCM_PLACR 0xF000300C
+/* Offsets */
+#define WDOG_STCTRLH_OFFSET 0
+#define WDOG32_CS_OFFSET 0
+
/* Values */
#define PM_STAT_RUN 0x01
#define PM_STAT_VLPR 0x04
@@ -270,13 +277,26 @@ struct kinetis_chip {
FS_PROGRAM_SECTOR = 1,
FS_PROGRAM_LONGWORD = 2,
FS_PROGRAM_PHRASE = 4, /* Unsupported */
- FS_INVALIDATE_CACHE_K = 8, /* using FMC->PFB0CR/PFB01CR */
- FS_INVALIDATE_CACHE_L = 0x10, /* using MCM->PLACR */
- FS_INVALIDATE_CACHE_MSCM = 0x20,
+
FS_NO_CMD_BLOCKSTAT = 0x40,
FS_WIDTH_256BIT = 0x80,
} flash_support;
+ enum {
+ KINETIS_CACHE_NONE,
+ KINETIS_CACHE_K, /* invalidate using FMC->PFB0CR/PFB01CR */
+ KINETIS_CACHE_L, /* invalidate using MCM->PLACR */
+ KINETIS_CACHE_MSCM, /* devices like KE1xF, invalidate MSCM->OCMDR0 */
+ } cache_type;
+
+ enum {
+ KINETIS_WDOG_NONE,
+ KINETIS_WDOG_K,
+ KINETIS_WDOG_COP,
+ KINETIS_WDOG32_KE1X,
+ KINETIS_WDOG32_KL28,
+ } watchdog_type;
+
char name[40];
unsigned num_banks;
@@ -362,6 +382,7 @@ static bool create_banks;
struct flash_driver kinetis_flash;
static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count);
+static int kinetis_probe_chip(struct kinetis_chip *k_chip);
static int kinetis_auto_probe(struct flash_bank *bank);
@@ -941,11 +962,53 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
}
-/* Disable the watchdog on Kinetis devices */
-int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
+static int kinetis_disable_wdog_algo(struct target *target, size_t code_size, const uint8_t *code, uint32_t wdog_base)
{
struct working_area *wdog_algorithm;
struct armv7m_algorithm armv7m_info;
+ struct reg_param reg_params[1];
+ int retval;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ retval = target_alloc_working_area(target, code_size, &wdog_algorithm);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_buffer(target, wdog_algorithm->address,
+ code_size, code);
+ if (retval == ERROR_OK) {
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN);
+ buf_set_u32(reg_params[0].value, 0, 32, wdog_base);
+
+ retval = target_run_algorithm(target, 0, NULL, 1, reg_params,
+ wdog_algorithm->address,
+ wdog_algorithm->address + code_size - 2,
+ 500, &armv7m_info);
+
+ destroy_reg_param(&reg_params[0]);
+
+ if (retval != ERROR_OK)
+ LOG_ERROR("Error executing Kinetis WDOG unlock algorithm");
+ }
+
+ target_free_working_area(target, wdog_algorithm);
+
+ return retval;
+}
+
+/* Disable the watchdog on Kinetis devices
+ * Standard Kx WDOG peripheral checks timing and therefore requires to run algo.
+ */
+static int kinetis_disable_wdog_kx(struct target *target)
+{
+ const uint32_t wdog_base = WDOG_BASE;
uint16_t wdog;
int retval;
@@ -953,14 +1016,7 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc"
};
- /* Decide whether the connected device needs watchdog disabling.
- * Disable for all Kx and KVx devices, return if it is a KLx */
-
- if ((sim_sdid & KINETIS_SDID_SERIESID_MASK) == KINETIS_SDID_SERIESID_KL)
- return ERROR_OK;
-
- /* The connected device requires watchdog disabling. */
- retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+ retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
if (retval != ERROR_OK)
return retval;
@@ -968,60 +1024,116 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
/* watchdog already disabled */
return ERROR_OK;
}
- LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog);
+ LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%04" PRIx16 ")", wdog);
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
+ retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
+ if (retval != ERROR_OK)
+ return retval;
- retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm);
+ retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
if (retval != ERROR_OK)
return retval;
- retval = target_write_buffer(target, wdog_algorithm->address,
- sizeof(kinetis_unlock_wdog_code), (uint8_t *)kinetis_unlock_wdog_code);
- if (retval != ERROR_OK) {
- target_free_working_area(target, wdog_algorithm);
+ LOG_INFO("WDOG_STCTRLH = 0x%04" PRIx16, wdog);
+ return (wdog & 0x1) ? ERROR_FAIL : ERROR_OK;
+}
+
+static int kinetis_disable_wdog32(struct target *target, uint32_t wdog_base)
+{
+ uint32_t wdog_cs;
+ int retval;
+
+ static const uint8_t kinetis_unlock_wdog_code[] = {
+#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc"
+ };
+
+ retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
+ if (retval != ERROR_OK)
return retval;
- }
- armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
- armv7m_info.core_mode = ARM_MODE_THREAD;
+ if ((wdog_cs & 0x80) == 0)
+ return ERROR_OK; /* watchdog already disabled */
- retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address,
- wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2),
- 10000, &armv7m_info);
+ LOG_INFO("Disabling Kinetis watchdog (initial WDOG_CS 0x%08" PRIx32 ")", wdog_cs);
+ retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
if (retval != ERROR_OK)
- LOG_ERROR("error executing kinetis wdog unlock algorithm");
+ return retval;
- retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+ retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
if (retval != ERROR_OK)
return retval;
- LOG_INFO("WDOG_STCTRLH = 0x%x", wdog);
- target_free_working_area(target, wdog_algorithm);
+ if ((wdog_cs & 0x80) == 0)
+ return ERROR_OK; /* watchdog disabled successfully */
- return retval;
+ LOG_ERROR("Cannot disable Kinetis watchdog (WDOG_CS 0x%08" PRIx32 "), issue 'reset init'", wdog_cs);
+ return ERROR_FAIL;
+}
+
+static int kinetis_disable_wdog(struct kinetis_chip *k_chip)
+{
+ struct target *target = k_chip->target;
+ uint8_t sim_copc;
+ int retval;
+
+ if (!k_chip->probed) {
+ retval = kinetis_probe_chip(k_chip);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ switch (k_chip->watchdog_type) {
+ case KINETIS_WDOG_K:
+ return kinetis_disable_wdog_kx(target);
+
+ case KINETIS_WDOG_COP:
+ retval = target_read_u8(target, SIM_COPC, &sim_copc);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if ((sim_copc & 0xc) == 0)
+ return ERROR_OK; /* watchdog already disabled */
+
+ LOG_INFO("Disabling Kinetis watchdog (initial SIM_COPC 0x%02" PRIx8 ")", sim_copc);
+ retval = target_write_u8(target, SIM_COPC, sim_copc & ~0xc);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u8(target, SIM_COPC, &sim_copc);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if ((sim_copc & 0xc) == 0)
+ return ERROR_OK; /* watchdog disabled successfully */
+
+ LOG_ERROR("Cannot disable Kinetis watchdog (SIM_COPC 0x%02" PRIx8 "), issue 'reset init'", sim_copc);
+ return ERROR_FAIL;
+
+ case KINETIS_WDOG32_KE1X:
+ return kinetis_disable_wdog32(target, WDOG32_KE1X);
+
+ case KINETIS_WDOG32_KL28:
+ return kinetis_disable_wdog32(target, WDOG32_KL28);
+
+ default:
+ return ERROR_OK;
+ }
}
COMMAND_HANDLER(kinetis_disable_wdog_handler)
{
int result;
- uint32_t sim_sdid;
struct target *target = get_current_target(CMD_CTX);
+ struct kinetis_chip *k_chip = kinetis_get_chip(target);
+
+ if (k_chip == NULL)
+ return ERROR_FAIL;
if (CMD_ARGC > 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- result = target_read_u32(target, SIM_SDID, &sim_sdid);
- if (result != ERROR_OK) {
- LOG_ERROR("Failed to read SIMSDID");
- return result;
- }
-
- result = kinetis_disable_wdog(target, sim_sdid);
+ result = kinetis_disable_wdog(k_chip);
return result;
}
@@ -1400,20 +1512,26 @@ static void kinetis_invalidate_flash_cache(struct kinetis_chip *k_chip)
{
struct target *target = k_chip->target;
- if (k_chip->flash_support & FS_INVALIDATE_CACHE_K)
+ switch (k_chip->cache_type) {
+ case KINETIS_CACHE_K:
target_write_u8(target, FMC_PFB01CR + 2, 0xf0);
/* Set CINV_WAY bits - request invalidate of all cache ways */
/* FMC_PFB0CR has same address and CINV_WAY bits as FMC_PFB01CR */
+ break;
- else if (k_chip->flash_support & FS_INVALIDATE_CACHE_L)
+ case KINETIS_CACHE_L:
target_write_u8(target, MCM_PLACR + 1, 0x04);
/* set bit CFCC - Clear Flash Controller Cache */
+ break;
- else if (k_chip->flash_support & FS_INVALIDATE_CACHE_MSCM)
+ case KINETIS_CACHE_MSCM:
target_write_u32(target, MSCM_OCMDR0, 0x30);
/* disable data prefetch and flash speculate */
+ break;
- return;
+ default:
+ break;
+ }
}
@@ -1647,7 +1765,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
uint32_t words_remaining = count / 4;
- kinetis_disable_wdog(bank->target, k_chip->sim_sdid);
+ kinetis_disable_wdog(k_chip);
/* try using a block write */
result = kinetis_write_block(bank, buffer, offset, words_remaining);
@@ -1791,6 +1909,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
if ((k_chip->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
/* older K-series MCU */
uint32_t mcu_type = k_chip->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
+ k_chip->cache_type = KINETIS_CACHE_K;
+ k_chip->watchdog_type = KINETIS_WDOG_K;
switch (mcu_type) {
case KINETIS_K_SDID_K10_M50:
@@ -1799,7 +1919,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->pflash_sector_size = 1<<10;
k_chip->nvm_sector_size = 1<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
break;
case KINETIS_K_SDID_K10_M72:
case KINETIS_K_SDID_K20_M72:
@@ -1812,7 +1932,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->pflash_sector_size = 2<<10;
k_chip->nvm_sector_size = 1<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
k_chip->max_flash_prog_size = 1<<10;
break;
case KINETIS_K_SDID_K10_M100:
@@ -1828,7 +1948,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->pflash_sector_size = 2<<10;
k_chip->nvm_sector_size = 2<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
break;
case KINETIS_K_SDID_K21_M120:
case KINETIS_K_SDID_K22_M120:
@@ -1837,7 +1957,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->max_flash_prog_size = 1<<10;
k_chip->nvm_sector_size = 4<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
break;
case KINETIS_K_SDID_K10_M120:
case KINETIS_K_SDID_K20_M120:
@@ -1847,7 +1967,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->pflash_sector_size = 4<<10;
k_chip->nvm_sector_size = 4<<10;
num_blocks = 4;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
break;
default:
LOG_ERROR("Unsupported K-family FAMID");
@@ -1869,12 +1989,15 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
switch (k_chip->sim_sdid & KINETIS_SDID_SERIESID_MASK) {
case KINETIS_SDID_SERIESID_K:
use_nvm_marking = true;
+ k_chip->cache_type = KINETIS_CACHE_K;
+ k_chip->watchdog_type = KINETIS_WDOG_K;
+
switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
case KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2:
/* K02FN64, K02FN128: FTFA, 2kB sectors */
k_chip->pflash_sector_size = 2<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
cpu_mhz = 100;
break;
@@ -1890,7 +2013,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* MK24FN1M */
k_chip->pflash_sector_size = 4<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
k_chip->max_flash_prog_size = 1<<10;
subfamid = 4; /* errata 1N83J fix */
break;
@@ -1901,7 +2024,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
k_chip->pflash_sector_size = 2<<10;
/* autodetect 1 or 2 blocks */
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
break;
}
LOG_ERROR("Unsupported Kinetis K22 DIEID");
@@ -1912,12 +2035,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
if ((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
/* K24FN256 - smaller pflash with FTFA */
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
break;
}
/* K24FN1M without errata 7534 */
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
k_chip->max_flash_prog_size = 1<<10;
break;
@@ -1932,7 +2055,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->nvm_sector_size = 4<<10;
k_chip->max_flash_prog_size = 1<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
break;
case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
@@ -1943,7 +2066,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->nvm_sector_size = 4<<10;
k_chip->max_flash_prog_size = 1<<10;
num_blocks = 4;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
cpu_mhz = 180;
break;
@@ -1953,7 +2076,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* K80FN256, K81FN256, K82FN256 */
k_chip->pflash_sector_size = 4<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K | FS_NO_CMD_BLOCKSTAT;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
cpu_mhz = 150;
break;
@@ -1962,7 +2085,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* KL81Z128, KL82Z128 */
k_chip->pflash_sector_size = 2<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L | FS_NO_CMD_BLOCKSTAT;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
+ k_chip->cache_type = KINETIS_CACHE_L;
+
use_nvm_marking = false;
snprintf(name, sizeof(name), "MKL8%uZ%%s7",
subfamid);
@@ -1982,7 +2107,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->pflash_sector_size = 1<<10;
k_chip->nvm_sector_size = 1<<10;
/* autodetect 1 or 2 blocks */
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
+ k_chip->cache_type = KINETIS_CACHE_L;
+ k_chip->watchdog_type = KINETIS_WDOG_COP;
cpu_mhz = 48;
if (subfamid == 3 && (familyid == 1 || familyid == 2))
@@ -1993,12 +2120,14 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
case KINETIS_SDID_SERIESID_KV:
/* KV-series */
+ k_chip->watchdog_type = KINETIS_WDOG_K;
switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0:
/* KV10: FTFA, 1kB sectors */
k_chip->pflash_sector_size = 1<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
+ k_chip->cache_type = KINETIS_CACHE_L;
strcpy(name, "MKV10Z%s7");
break;
@@ -2006,7 +2135,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* KV11: FTFA, 2kB sectors */
k_chip->pflash_sector_size = 2<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
+ k_chip->cache_type = KINETIS_CACHE_L;
strcpy(name, "MKV11Z%s7");
break;
@@ -2016,7 +2146,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* KV31: FTFA, 2kB sectors, 2 blocks */
k_chip->pflash_sector_size = 2<<10;
/* autodetect 1 or 2 blocks */
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
+ k_chip->cache_type = KINETIS_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:
@@ -2025,7 +2156,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
/* KV4x: FTFA, 4kB sectors */
k_chip->pflash_sector_size = 4<<10;
num_blocks = 1;
- k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ k_chip->flash_support = FS_PROGRAM_LONGWORD;
+ k_chip->cache_type = KINETIS_CACHE_K;
cpu_mhz = 168;
break;
@@ -2053,6 +2185,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
case KINETIS_SDID_SERIESID_KE:
/* KE1x-series */
+ k_chip->watchdog_type = KINETIS_WDOG32_KE1X;
switch (k_chip->sim_sdid &
(KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK | KINETIS_SDID_PROJECTID_MASK)) {
case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1xZ:
@@ -2062,7 +2195,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->nvm_sector_size = 2<<10;
k_chip->max_flash_prog_size = 1<<9;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_L;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ k_chip->cache_type = KINETIS_CACHE_L;
cpu_mhz = 72;
snprintf(name, sizeof(name), "MKE%u%uZ%%s%u",
@@ -2077,7 +2211,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
k_chip->nvm_sector_size = 2<<10;
k_chip->max_flash_prog_size = 1<<10;
num_blocks = 2;
- k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_MSCM;
+ k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ k_chip->cache_type = KINETIS_CACHE_MSCM;
cpu_mhz = 168;
snprintf(name, sizeof(name), "MKE%u%uF%%s%u",
diff --git a/tcl/target/klx.cfg b/tcl/target/klx.cfg
index c2de9f7..7dd0404 100644
--- a/tcl/target/klx.cfg
+++ b/tcl/target/klx.cfg
@@ -37,7 +37,8 @@ flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
kinetis create_banks
# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 1MHz for VLPR mode.
+# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;
+# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.
adapter_khz 1000
reset_config srst_nogate
@@ -53,10 +54,9 @@ if {![using_hla]} {
cortex_m reset_config sysresetreq
}
-# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 24MHz for run mode; Table 17 of Sub-Family Data
-# Sheet rev4 lists 25MHz as the maximum frequency.
-# Uncoment only if VLPR mode is not used
-#$_TARGETNAME configure -event reset-init {
-# adapter_khz 24000
-#}
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+ kinetis disable_wdog
+}
diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg
index cf77713..7b03517 100644
--- a/tcl/target/kx.cfg
+++ b/tcl/target/kx.cfg
@@ -54,3 +54,11 @@ if {![using_hla]} {
# perform a soft reset
cortex_m reset_config sysresetreq
}
+
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+ kinetis disable_wdog
+}
+