From 751e2454bf076708d3e695833c4def460ab41d8b Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 15 May 2015 11:14:11 +0200 Subject: [PATCH] at91samd: handle reset run/halt in DSU Atmel introduced a "Device Service Unit" (DSU) that holds the CPU in reset if TCK is low when srst (RESET_N) is deasserted. Function is similar to SMAP in ATSAM4L, see http://openocd.zylin.com/2604 Atmel's EDBG adapter handles DSU reset correctly without this change. An ordinary SWD adapter leaves TCK in its default state, low. So without this change any use of sysresetreq or srst locks the chip in reset state until power is cycled. A new function dsu_reset_deassert is called as reset-deassert-post event handler. It optionally prepares reset vector catch and DSU reset is released then. Additionally SWD clock comment is fixed in at91samdXX.cfg and clock is lowered a bit to ensure a margin for RC oscillator frequency deviation. adapter_nsrst_delay 100 is commented out because is no more necessary after http://openocd.zylin.com/2601 Change-Id: I42e99b1b245f766616c0a0d939f60612c29bd16c Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/2778 Tested-by: jenkins Reviewed-by: Spencer Oliver --- doc/openocd.texi | 9 ++++++++ src/flash/nor/at91samd.c | 42 ++++++++++++++++++++++++++++++++++++++ tcl/target/at91samdXX.cfg | 43 +++++++++++++++++++++++++++++++-------- 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 7ae2a3f09d..14835a919c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4933,6 +4933,9 @@ flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME @anchor{at91samd} @deffn {Flash Driver} at91samd @cindex at91samd +All members of the ATSAMD, ATSAMR, ATSAML and ATSAMC microcontroller +families from Atmel include internal flash and use ARM's Cortex-M0+ core. +This driver uses the same cmd names/syntax as @xref{at91sam3}. @deffn Command {at91samd chip-erase} Issues a complete Flash erase via the Device Service Unit (DSU). This can be @@ -4980,6 +4983,12 @@ at91samd bootloader 16384 @end example @end deffn +@deffn Command {at91samd dsu_reset_deassert} +This command releases internal reset held by DSU +and prepares reset vector catch in case of reset halt. +Command is used internally in event event reset-deassert-post. +@end deffn + @end deffn @anchor{at91sam3} diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index a4cc51d21d..9b0f7eebe5 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -25,6 +25,8 @@ #include "imp.h" #include "helper/binarybuffer.h" +#include + #define SAMD_NUM_SECTORS 16 #define SAMD_PAGE_SIZE_MAX 1024 @@ -34,6 +36,7 @@ #define SAMD_DSU 0x41002000 /* Device Service Unit */ #define SAMD_NVMCTRL 0x41004000 /* Non-volatile memory controller */ +#define SAMD_DSU_STATUSA 1 /* DSU status register */ #define SAMD_DSU_DID 0x18 /* Device ID register */ #define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */ @@ -1038,7 +1041,46 @@ COMMAND_HANDLER(samd_handle_bootloader_command) return res; } + + +COMMAND_HANDLER(samd_handle_reset_deassert) +{ + struct target *target = get_current_target(CMD_CTX); + struct armv7m_common *armv7m = target_to_armv7m(target); + struct adiv5_dap *swjdp = armv7m->arm.dap; + int retval = ERROR_OK; + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset() + * so we just release reset held by DSU + * + * n_RESET (srst) clears the DP, so reenable debug and set vector catch here + * + * After vectreset DSU release is not needed however makes no harm + */ + if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) { + retval = mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN); + if (retval == ERROR_OK) + retval = mem_ap_write_u32(swjdp, DCB_DEMCR, + TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); + /* do not return on error here, releasing DSU reset is more important */ + } + + /* clear CPU Reset Phase Extension bit */ + int retval2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1)); + if (retval2 != ERROR_OK) + return retval2; + + return retval; +} + static const struct command_registration at91samd_exec_command_handlers[] = { + { + .name = "dsu_reset_deassert", + .handler = samd_handle_reset_deassert, + .mode = COMMAND_EXEC, + .help = "deasert internal reset held by DSU" + }, { .name = "info", .handler = samd_handle_info_command, diff --git a/tcl/target/at91samdXX.cfg b/tcl/target/at91samdXX.cfg index fb3be04a4b..50d93f5903 100644 --- a/tcl/target/at91samdXX.cfg +++ b/tcl/target/at91samdXX.cfg @@ -1,5 +1,5 @@ # -# script for ATMEL samdXX, a CORTEX-M0 chip +# script for Atmel SAMD, SAMR, SAML or SAMC, a CORTEX-M0 chip # # @@ -40,15 +40,42 @@ target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAM $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz +# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N +# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2) # -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. +# dsu_reset_deassert configures whether we want to run or halt out of reset, +# then instruct the DSU to let us out of reset. +$_TARGETNAME configure -event reset-deassert-post { + at91samd dsu_reset_deassert +} + +# SRST (wired to RESET_N) resets debug circuitry +# srst_pulls_trst is not configured here to avoid an error raised in reset halt +reset_config srst_gates_jtag + +# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) cannot +# stop the MCU before it starts executing code if hardware RESETN +# line is configured by command "reset_config srst_only" +# Use "reset_config none" (default) before flash programming. + +# Do not use a reset button with other SWD adapter than Atmel's EDBG. +# DSU usually locks MCU in reset state until you issue a reset command +# in OpenOCD. + +# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset. +# Other members of family usually use SYSCLK = 4 MHz after reset. +# Datasheet does not specify SYSCLK to SWD clock ratio. +# Usually used SYSCLK/6 is slow, testing shows that debugging can +# work @ SYSCLK/2 but your mileage may vary. +# This limit is most probably imposed by incorrectly handled SWD WAIT +# on some SWD adapters. + +adapter_khz 400 -adapter_khz 500 -adapter_nsrst_delay 100 +# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works +# without problem at maximal clock speed. Atmel recommends +# adapter speed less than 10 * CPU clock. +# adapter_khz 5000 if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to -- 2.30.2