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

Reply via email to