aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi9
-rw-r--r--src/flash/nor/at91samd.c42
-rw-r--r--tcl/target/at91samdXX.cfg43
3 files changed, 86 insertions, 8 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 7ae2a3f0..14835a91 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 a4cc51d2..9b0f7eeb 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 <target/cortex_m.h>
+
#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,8 +1041,47 @@ 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,
.mode = COMMAND_EXEC,
diff --git a/tcl/target/at91samdXX.cfg b/tcl/target/at91samdXX.cfg
index fb3be04a..50d93f59 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