This is an automated email from Gerrit. Thomas Schmid ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/2986
-- gerrit commit bb2b0203767ea72bb1f2602a22cafcad2caed26c Author: Thomas Schmid <[email protected]> Date: Wed Sep 30 09:40:10 2015 -0600 Kinetis: Disable the watchdog on K22FNxx devices when programming. The K22 needs the watchdog disabled when programming. I tried to keep overhead as small as possible and re-use registers that were already inquired (e.g. sim_sdid). Change-Id: Ibc29a26ec34102d78a6c3920dd16f63e134a8f6f Signed-off-by: Thomas Schmid <[email protected]> diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index ba3f5ea..e53cae4 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -77,15 +77,16 @@ */ /* Addressess */ -#define FLEXRAM 0x14000000 -#define FTFx_FSTAT 0x40020000 -#define FTFx_FCNFG 0x40020001 -#define FTFx_FCCOB3 0x40020004 -#define FTFx_FPROT3 0x40020010 -#define SIM_SDID 0x40048024 -#define SIM_SOPT1 0x40047000 -#define SIM_FCFG1 0x4004804c -#define SIM_FCFG2 0x40048050 +#define FLEXRAM 0x14000000 +#define FTFx_FSTAT 0x40020000 +#define FTFx_FCNFG 0x40020001 +#define FTFx_FCCOB3 0x40020004 +#define FTFx_FPROT3 0x40020010 +#define SIM_SDID 0x40048024 +#define SIM_SOPT1 0x40047000 +#define SIM_FCFG1 0x4004804c +#define SIM_FCFG2 0x40048050 +#define WDOG_STCTRLH 0x40052000 /* Commands */ #define FTFx_CMD_BLOCKSTAT 0x00 @@ -508,6 +509,94 @@ FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command) return ERROR_OK; } +/* Disable the watchdog on Kinetis devices */ +int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid) +{ + struct working_area *wdog_algorithm; + struct armv7m_algorithm armv7m_info; + uint16_t wdog; + 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 */ + }; + + /* Decide whether the connected device needs watchdog disabling. */ + + /* Is the K22 the only one that needs this? */ + if (!((sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN128 + || (sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN256 + || (sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN512)) { + return ERROR_OK; + } + + /* The connected device requires watchdog disabling. */ + retval = target_read_u16(target, WDOG_STCTRLH, &wdog); + if (retval != ERROR_OK) + return retval; + + if ((wdog & 0x1) == 0) { + /* watchdog already disabled */ + return ERROR_OK; + } + LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog); + + retval = target_halt(target); + if (retval != ERROR_OK) + return retval; + target->state = TARGET_HALTED; + + retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm); + 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); + return retval; + } + + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; + + retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address, + wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2), + 10000, &armv7m_info); + + if (retval != ERROR_OK) + LOG_ERROR("error executing kinetis wdog unlock algorithm"); + + retval = target_read_u16(target, WDOG_STCTRLH, &wdog); + if (retval != ERROR_OK) + return retval; + LOG_INFO("WDOG_STCTRLH = 0x%x", wdog); + + target_free_working_area(target, wdog_algorithm); + + return retval; +} + + /* Kinetis Program-LongWord Microcodes */ static const uint8_t kinetis_flash_write_code[] = { /* Params: @@ -1015,6 +1104,8 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t words_remaining = count / 4; + kinetis_disable_wdog(bank->target, kinfo->sim_sdid); + /* try using a block write */ int retval = kinetis_write_block(bank, buffer, offset, words_remaining); -- ------------------------------------------------------------------------------ _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
