AT91SAM4L: handle reset run/halt in SMAP
This is a remake of http://openocd.zylin.com/1966 originally written by Angus Gratton <gus@projectgus.com> 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 <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/2604 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
parent
bdfd5bbe04
commit
f3b1405fdd
|
@ -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
|
||||
|
|
|
@ -24,13 +24,15 @@
|
|||
|
||||
#include "imp.h"
|
||||
|
||||
#include <target/cortex_m.h>
|
||||
|
||||
/* 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",
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue