From 3de3de0b37ec1bec5da7b3737a063fe28c332d46 Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Mon, 10 Nov 2008 10:16:13 +0000
Subject: [PATCH] execute reset init upon power restore / srst deassert

git-svn-id: svn://svn.berlios.de/openocd/trunk@1150 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/helper/startup.tcl | 20 +++++++++++++
 src/target/target.c    | 64 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 75940e914..f91ba7ed5 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -327,3 +327,23 @@ proc cpu {args} {
 	}
 }
 
+proc power_restore {} {
+	puts "Sensed power restore."
+	reset init
+}
+
+add_help_text power_restore "Overridable procedure run when power restore is detected. Runs 'reset init' by default."
+
+proc power_dropout {} {
+	puts "Sensed power dropout."
+}
+
+proc srst_deasserted {} {
+	puts "Sensed nSRST deasserted."
+	reset init
+}
+add_help_text srst_deasserted "Overridable procedure run when srst deassert is detected. Runs 'reset init' by default."
+
+proc srst_asserted {} {
+	puts "Sensed nSRST asserted."
+}
diff --git a/src/target/target.c b/src/target/target.c
index 66c80f4e7..5e8cf7486 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1458,6 +1458,11 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch
 static int powerDropout;
 static int srstAsserted;
 
+static int runPowerRestore;
+static int runPowerDropout;
+static int runSrstAsserted;
+static int runSrstDeasserted;
+
 static int sense_handler()
 {
 	static int prevSrstAsserted = 0;
@@ -1471,7 +1476,7 @@ static int sense_handler()
 	powerRestored = prevPowerdropout && !powerDropout;
 	if (powerRestored)
 	{
-		LOG_USER("Sensed power restore.");
+		runPowerRestore = 1;
 	}
 
 	long long current = timeval_ms();
@@ -1479,7 +1484,7 @@ static int sense_handler()
 	int waitMore = lastPower + 2000 > current;
 	if (powerDropout && !waitMore)
 	{
-		LOG_USER("Sensed power dropout.");
+		runPowerDropout = 1;
 		lastPower = current;
 	}
 
@@ -1493,13 +1498,13 @@ static int sense_handler()
 	waitMore = lastSrst + 2000 > current;
 	if (srstDeasserted && !waitMore)
 	{
-		LOG_USER("Sensed nSRST deasserted");
+		runSrstDeasserted = 1;
 		lastSrst = current;
 	}
 
 	if (!prevSrstAsserted && srstAsserted)
 	{
-		LOG_USER("Sensed nSRST asserted");
+		runSrstAsserted = 1;
 	}
 
 	prevSrstAsserted = srstAsserted;
@@ -1521,11 +1526,59 @@ static int sense_handler()
 int handle_target(void *priv)
 {
 	int retval = ERROR_OK;
+
+	/* we do not want to recurse here... */
+	static int recursive = 0;
+	if (! recursive)
+	{
+		recursive = 1;
+		sense_handler();
+		/* danger! running these procedures can trigger srst assertions and power dropouts.
+		 * We need to avoid an infinite loop/recursion here and we do that by
+		 * clearing the flags after running these events.
+		 */
+		int did_something = 0;
+		if (runSrstAsserted)
+		{
+			Jim_Eval( interp, "srst_asserted");
+			did_something = 1;
+		}
+		if (runSrstDeasserted)
+		{
+			Jim_Eval( interp, "srst_deasserted");
+			did_something = 1;
+		}
+		if (runPowerDropout)
+		{
+			Jim_Eval( interp, "power_dropout");
+			did_something = 1;
+		}
+		if (runPowerRestore)
+		{
+			Jim_Eval( interp, "power_restore");
+			did_something = 1;
+		}
+
+		if (did_something)
+		{
+			/* clear detect flags */
+			sense_handler();
+		}
+
+		/* clear action flags */
+
+		runSrstAsserted=0;
+		runSrstDeasserted=0;
+		runPowerRestore=0;
+		runPowerDropout=0;
+
+		recursive = 0;
+	}
+
 	target_t *target = all_targets;
 
 	while (target)
 	{
-		sense_handler();
 
 		/* only poll target if we've got power and srst isn't asserted */
 		if (target_continous_poll&&!powerDropout&&!srstAsserted)
@@ -1538,6 +1591,7 @@ int handle_target(void *priv)
 		target = target->next;
 	}
 
+
 	return retval;
 }
 
-- 
GitLab