From baf08b0a1ad656434583e3c102a350d4cf885bf9 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sat, 19 Dec 2015 12:34:31 +0100 Subject: [PATCH] flash Kinetis: new KVx family added Cortex-M0+ and M4 motor control MCUs KV10, KV11, KV30, KV31, KV42, KV44 and KV46 added to SDID identification. Watchdog disable code changed to work on Cortex-M0+ (KV1x) Protection size set to 1K for 16K flash devices (KV10Z16) - cherry picked from Andrey Smirnov's change #2051 Change-Id: Ia6f4868eaf7e2cb6ad6a736210c703a67e0027be Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/3235 Tested-by: jenkins Reviewed-by: Kyle Manna Reviewed-by: Freddie Chopin --- contrib/loaders/watchdog/Makefile | 19 +++++ .../loaders/watchdog/armv7m_kinetis_wdog.inc | 4 ++ .../loaders/watchdog/armv7m_kinetis_wdog.s | 64 +++++++++++++++++ src/flash/nor/kinetis.c | 70 +++++++++++++------ 4 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 contrib/loaders/watchdog/Makefile create mode 100644 contrib/loaders/watchdog/armv7m_kinetis_wdog.inc create mode 100644 contrib/loaders/watchdog/armv7m_kinetis_wdog.s diff --git a/contrib/loaders/watchdog/Makefile b/contrib/loaders/watchdog/Makefile new file mode 100644 index 000000000..d9ef1d2c5 --- /dev/null +++ b/contrib/loaders/watchdog/Makefile @@ -0,0 +1,19 @@ +BIN2C = ../../../src/helper/bin2char.sh + +ARM_CROSS_COMPILE ?= arm-none-eabi- +ARM_AS ?= $(ARM_CROSS_COMPILE)as +ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy + +arm: armv7m_kinetis_wdog.inc + +armv7m_%.elf: armv7m_%.s + $(ARM_AS) -mthumb $< -o $@ + +armv7m_%.bin: armv7m_%.elf + $(ARM_OBJCOPY) -Obinary $< $@ + +armv7m_%.inc: armv7m_%.bin + $(BIN2C) < $< > $@ + +clean: + -rm -f *.elf *.bin *.inc diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc new file mode 100644 index 000000000..4b6579e0c --- /dev/null +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc @@ -0,0 +1,4 @@ +/* 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, diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s new file mode 100644 index 000000000..bac924ab8 --- /dev/null +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2015 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 for Kinetis Kx and KVx + Parameters: none + Used instruction set should work on both Cortex-M4 and M0+ +*/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + +WDOG_ADDR = 0x40052000 +/* WDOG registers offsets */ +WDOG_STCTRLH = 0 +WDOG_UNLOCK = 0x0e + +WDOG_KEY1 = 0xc520 +WDOG_KEY2 = 0xd928 + + .thumb_func +start: +/* WDOG_UNLOCK = 0xC520 */ + ldr r3, =WDOG_ADDR + ldr r2, =WDOG_KEY1 + strh r2, [r3, WDOG_UNLOCK] +/* WDOG_UNLOCK = 0xD928 */ + ldr r2, =WDOG_KEY2 + strh r2, [r3, WDOG_UNLOCK] +/* WDOG_STCTRLH clear bit 0 */ + movs r4, #1 + ldrh r2, [r3, WDOG_STCTRLH] + bics r2, r4 + strh r2, [r3, WDOG_STCTRLH] +/* 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 3d2fa1c64..4749c7bbd 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -555,30 +555,11 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid) int retval; static const uint8_t kinetis_unlock_wdog_code[] = { - /* WDOG_UNLOCK = 0xC520 */ - 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */ - 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */ - 0x4c, 0xf2, 0x20, 0x52, /* movw r2, #50464 ; 0xc520 */ - 0xda, 0x81, /* strh r2, [r3, #14] */ - - /* WDOG_UNLOCK = 0xD928 */ - 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */ - 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */ - 0x4d, 0xf6, 0x28, 0x12, /* movw r2, #55592 ; 0xd928 */ - 0xda, 0x81, /* strh r2, [r3, #14] */ - - /* WDOG_SCR = 0x1d2 */ - 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */ - 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */ - 0x4f, 0xf4, 0xe9, 0x72, /* mov.w r2, #466 ; 0x1d2 */ - 0x1a, 0x80, /* strh r2, [r3, #0] */ - - /* END */ - 0x00, 0xBE, /* bkpt #0 */ +#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc" }; /* Decide whether the connected device needs watchdog disabling. - * Disable for all Kx devices, i.e., return if it is a KLx */ + * 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; @@ -1410,6 +1391,7 @@ static int kinetis_probe(struct flash_bank *bank) LOG_ERROR("Unsupported Kinetis FAMILYID SUBFAMID"); } break; + case KINETIS_SDID_SERIESID_KL: /* KL-series */ pflash_sector_size_bytes = 1<<10; @@ -1417,6 +1399,47 @@ static int kinetis_probe(struct flash_bank *bank) /* autodetect 1 or 2 blocks */ kinfo->flash_support = FS_PROGRAM_LONGWORD; break; + + case KINETIS_SDID_SERIESID_KV: + /* KV-series */ + switch (kinfo->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) { + case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0: + /* KV10: FTFA, 1kB sectors */ + pflash_sector_size_bytes = 1<<10; + num_blocks = 1; + kinfo->flash_support = FS_PROGRAM_LONGWORD; + break; + + case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX1: + /* KV11: FTFA, 2kB sectors */ + pflash_sector_size_bytes = 2<<10; + num_blocks = 1; + kinfo->flash_support = FS_PROGRAM_LONGWORD; + break; + + case KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX0: + /* KV30: FTFA, 2kB sectors, 1 block */ + case KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX1: + /* KV31: FTFA, 2kB sectors, 2 blocks */ + pflash_sector_size_bytes = 2<<10; + /* autodetect 1 or 2 blocks */ + kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE; + break; + + case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2: + case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX4: + case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX6: + /* KV4x: FTFA, 4kB sectors */ + pflash_sector_size_bytes = 4<<10; + num_blocks = 1; + kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE; + break; + + default: + LOG_ERROR("Unsupported KV FAMILYID SUBFAMID"); + } + break; + default: LOG_ERROR("Unsupported K-series"); } @@ -1573,7 +1596,10 @@ static int kinetis_probe(struct flash_bank *bank) bank->base = 0x00000000 + bank->size * bank->bank_number; kinfo->prog_base = bank->base; kinfo->sector_size = pflash_sector_size_bytes; - kinfo->protection_size = pf_size / 32; + /* pflash is divided into 32 protection areas for + * parts with more than 32K of PFlash. For parts with + * less the protection unit is set to 1024 bytes */ + kinfo->protection_size = MAX(pf_size / 32, 1024); kinfo->protection_block = (32 / num_pflash_blocks) * bank->bank_number; } else if ((unsigned)bank->bank_number < num_blocks) {