From: Tomas Vanek Date: Sat, 14 Mar 2015 11:03:47 +0000 (+0100) Subject: AT91SAM4L: handle reset run/halt in SMAP X-Git-Tag: v0.9.0-rc1~24 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f3b1405fddf0b32af27ad3894841f7d1702d8e5a;p=openocd AT91SAM4L: handle reset run/halt in SMAP This is a remake of http://openocd.zylin.com/1966 originally written by Angus Gratton ATSAM4L has a "System Manager Access Port" (SMAP) that holds the CPU in reset if TCK is low when srst (RESET_N) is deasserted. Without this change any use of sysresetreq or srst locks the chip in reset state until power is cycled. A new function smap_reset_deassert is called as reset-deassert-post event handler. It optionally prepares reset vector catch and SMAP reset is released then. Change-Id: Iad736357b0f551725befa2b9e00f3bc54504f3d8 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/2604 Tested-by: jenkins Reviewed-by: Paul Fertser --- diff --git a/doc/openocd.texi b/doc/openocd.texi index e418e050..5a803d2c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5152,6 +5152,20 @@ Atmel include internal flash and use ARM's Cortex-M4 core. This driver uses the same cmd names/syntax as @xref{at91sam3}. @end deffn +@deffn {Flash Driver} at91sam4l +@cindex at91sam4l +All members of the AT91SAM4L microcontroller family from +Atmel include internal flash and use ARM's Cortex-M4 core. +This driver uses the same cmd names/syntax as @xref{at91sam3}. + +The AT91SAM4L driver adds some additional commands: +@deffn Command {at91sam4l smap_reset_deassert} +This command releases internal reset held by SMAP +and prepares reset vector catch in case of reset halt. +Command is used internally in event event reset-deassert-post. +@end deffn +@end deffn + @deffn {Flash Driver} at91sam7 All members of the AT91SAM7 microcontroller family from Atmel include internal flash and use ARM7TDMI cores. The driver automatically diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c index a5eb6727..74d5dbc6 100644 --- a/src/flash/nor/at91sam4l.c +++ b/src/flash/nor/at91sam4l.c @@ -24,13 +24,15 @@ #include "imp.h" +#include + /* At this time, the SAM4L Flash is available in these capacities: * ATSAM4Lx4xx: 256KB (512 pages) * ATSAM4Lx2xx: 128KB (256 pages) * ATSAM4Lx8xx: 512KB (1024 pages) */ -/* There are 16 lockable regions regardless of overall capacity. The number +/* There are 16 lockable regions regardless of overall capacity. The number * of pages per sector is therefore dependant on capacity. */ #define SAM4L_NUM_SECTORS 16 @@ -75,6 +77,14 @@ #define SAM4L_FMCD_CMDKEY 0xA5UL /* 'key' to issue commands, see 14.10.2 */ + +/* SMAP registers and bits */ +#define SMAP_BASE 0x400A3000 + +#define SMAP_SCR (SMAP_BASE + 8) +#define SMAP_SCR_HCR (1 << 1) + + struct sam4l_chip_info { uint32_t id; uint32_t exid; @@ -633,21 +643,47 @@ static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_OK; } -COMMAND_HANDLER(sam4l_handle_info_command) + +COMMAND_HANDLER(sam4l_handle_reset_deassert) { - return ERROR_OK; + 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 SMAP + * + * n_RESET (srst) clears the DP, so reenable debug and set vector catch here + * + * After vectreset SMAP 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_atomic_u32(swjdp, DCB_DEMCR, + TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); + /* do not return on error here, releasing SMAP reset is more important */ + } + + int retval2 = mem_ap_write_atomic_u32(swjdp, SMAP_SCR, SMAP_SCR_HCR); + if (retval2 != ERROR_OK) + return retval2; + + return retval; } static const struct command_registration at91sam4l_exec_command_handlers[] = { { - .name = "info", - .handler = sam4l_handle_info_command, + .name = "smap_reset_deassert", + .handler = sam4l_handle_reset_deassert, .mode = COMMAND_EXEC, - .help = "Print information about the current at91sam4l chip" - "and its flash configuration.", + .help = "deasert internal reset held by SMAP" }, COMMAND_REGISTRATION_DONE }; + static const struct command_registration at91sam4l_command_handlers[] = { { .name = "at91sam4l", diff --git a/tcl/target/at91sam4lXX.cfg b/tcl/target/at91sam4lXX.cfg index 93799a23..46c38aef 100644 --- a/tcl/target/at91sam4lXX.cfg +++ b/tcl/target/at91sam4lXX.cfg @@ -5,3 +5,23 @@ source [find target/at91sam4XXX.cfg] set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME + +# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N +# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3). +# +# smap_reset_deassert configures whether we want to run or halt out of reset, +# then instruct the SMAP to let us out of reset. +$_TARGETNAME configure -event reset-deassert-post "at91sam4l smap_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 + +# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed. +# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio. +# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2 +# but your mileage may vary. +adapter_khz 50 + +# System RC oscillator RCSYS starts in 3 cycles +adapter_nsrst_delay 0