SWD is not finished yet, a long way to go. Adding the actual hardware
drivers is a almost the last thing on my list. I want to get the
framework in place first.

What I have done is to get a SWD interface listed when you use 'openocd
-c interface_list'. There's a new struct (interface_base_t) added that
holds the interface type and name. The global variable
'chosen_interface' is type cast to 'jtag_interface_t *' or
'swd_interface_t *' as needed.

A new function called 'interface_init' is added that calls either
'jtag_interface_init' or 'swd_interface_init' as determined from the
'type' element in 'chosen_interface'.

I would really appreciate some constructive criticism on the code or the
patches. I'm new to git and to working with a community so I expect a
few teething probs.

How about some '#if BUILD_RLINK_SWD == 1' and '#if BUILD_SWD == 1' so
that SWD can be conditionally compiled? 

Thanks,
Andrew
>From 899af8f1eeebd37e42ee97b85c735f631724cffe Mon Sep 17 00:00:00 2001
From: Andrew Rogers <[email protected]>
Date: Fri, 13 Nov 2009 11:13:56 +0000
Subject: [PATCH] Added serial wire debug (SWD) interface struct.
 Added interface_base struct that can be typecast to jtag_interface or swd_interface.
 R-Link creates an swd_interface. 'openocd -c interface_list' lists both JTAG and SWD interfaces.

---
 src/jtag/core.c        |    1 +
 src/jtag/interface.h   |   20 ++++++++++++++++++++
 src/jtag/interfaces.c  |   15 +++++++++++++++
 src/jtag/interfaces.h  |    1 +
 src/jtag/rlink/rlink.c |   12 ++++++++++++
 src/jtag/tcl.c         |    7 +++++++
 6 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/src/jtag/core.c b/src/jtag/core.c
index bbe7425..ed26756 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -119,6 +119,7 @@ static struct jtag_interface_s *jtag = NULL;
 
 /* configuration */
 jtag_interface_t *jtag_interface = NULL;
+interface_base_t *chosen_interface = NULL;
 
 void jtag_set_error(int error)
 {
diff --git a/src/jtag/interface.h b/src/jtag/interface.h
index afe2108..b205af9 100644
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -184,8 +184,27 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf,
 }
 #endif // _DEBUG_JTAG_IO_
 
+typedef enum interface_type{
+  INTERFACE_JTAG, /* JTAG interface */
+  INTERFACE_SWD, /* Serial Wire Debug */
+  INTERFACE_UART /* UART */
+}interface_type_t;
+
+
+typedef struct interface_base_s
+{
+  /// The type of interface.
+  interface_type_t type;
+  
+  /// The name of the interface driver.
+  char * name;
+}interface_base_t;
+
 typedef struct jtag_interface_s
 {
+  /// The type of interface.
+  interface_type_t type;
+
 	/// The name of the JTAG interface driver.
 	char* name;
 
@@ -273,5 +292,6 @@ typedef struct jtag_interface_s
 	int (*srst_asserted)(int* srst_asserted);
 } jtag_interface_t;
 
+typedef struct jtag_interface_s swd_interface_t;
 
 #endif // OPENOCD_JTAG_INTERFACE_H
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 778c4e3..b55edfb 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -84,6 +84,7 @@ extern jtag_interface_t vsllink_interface;
 #endif
 #if BUILD_RLINK == 1
 extern jtag_interface_t rlink_interface;
+extern swd_interface_t rlink_interface_swd;
 #endif
 #if BUILD_ARMJTAGEW == 1
 extern jtag_interface_t armjtagew_interface;
@@ -149,6 +150,20 @@ jtag_interface_t *jtag_interfaces[] = {
 		NULL,
 	};
 
+/**
+ * The list of built-in SWD interfaces, containing entries for those
+ * drivers that were enabled by the @c configure script.
+ *
+ * The list should be defined to contain either one minidriver interface
+ * or some number of standard driver interfaces, never both.
+ */
+swd_interface_t *swd_interfaces[] = {
+#if BUILD_RLINK == 1
+                &rlink_interface_swd,
+#endif
+                NULL,
+        };
+
 void jtag_interface_modules_load(const char *path)
 {
 	// @todo: implement dynamic module loading for JTAG interface drivers
diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h
index a32d3f9..1716ac1 100644
--- a/src/jtag/interfaces.h
+++ b/src/jtag/interfaces.h
@@ -41,5 +41,6 @@
 void jtag_interface_modules_load(const char *path);
 
 extern jtag_interface_t *jtag_interfaces[];
+extern swd_interface_t *swd_interfaces[];
 
 #endif // OPENOCD_JTAG_INTERFACES_H
diff --git a/src/jtag/rlink/rlink.c b/src/jtag/rlink/rlink.c
index 3c85789..74eb0f2 100644
--- a/src/jtag/rlink/rlink.c
+++ b/src/jtag/rlink/rlink.c
@@ -1889,3 +1889,15 @@ jtag_interface_t rlink_interface =
 	.khz = rlink_khz,
 	.execute_queue = rlink_execute_queue,
 };
+
+swd_interface_t rlink_interface_swd =
+{
+        .name = "rlink-swd",
+        .init = rlink_init,
+        .quit = rlink_quit,
+        .register_commands = rlink_register_commands,
+        .speed = rlink_speed,
+        .speed_div = rlink_speed_div,
+        .khz = rlink_khz,
+        .execute_queue = rlink_execute_queue,
+};
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 923542f..c938acc 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -615,6 +615,13 @@ COMMAND_HANDLER(handle_interface_list_command)
 		command_print(cmd_ctx, "%u: %s", i + 1, name);
 	}
 
+	command_print(cmd_ctx, "The following SWD interfaces are available:");
+        for (unsigned i = 0; NULL != swd_interfaces[i]; i++)
+        {
+                const char *name = swd_interfaces[i]->name;
+                command_print(cmd_ctx, "%u: %s", i + 1, name);
+        }
+
 	return ERROR_OK;
 }
 
-- 
1.6.0.6

>From 23dc23297dd771e0d5bc86bf0c36cd00ad8c512d Mon Sep 17 00:00:00 2001
From: Andrew Rogers <[email protected]>
Date: Fri, 13 Nov 2009 13:15:08 +0000
Subject: [PATCH] New interface_init and swd_interface_init functions

swd_interface_init is a tweaked copy of jtag_interface_init but will change for SWD requirements.
interface_init chooses which init function to call based upon the interface type.
openocd.c now calls interface_init and not jtag_interface_init.
---
 src/jtag/core.c             |   75 +++++++++++++++++++++++++++++++++++++++++--
 src/jtag/jtag.h             |    2 +
 src/jtag/tcl.c              |   34 ++++++++++++++++++--
 src/openocd.c               |    6 ++--
 tcl/interface/rlink-swd.cfg |    8 ++++
 5 files changed, 116 insertions(+), 9 deletions(-)
 create mode 100644 tcl/interface/rlink-swd.cfg

diff --git a/src/jtag/core.c b/src/jtag/core.c
index ed26756..4dfcf3d 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -116,9 +116,9 @@ static enum {CLOCK_MODE_SPEED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
 static int jtag_speed = 0;
 
 static struct jtag_interface_s *jtag = NULL;
+static struct interface_base_s *interface = NULL;
 
 /* configuration */
-jtag_interface_t *jtag_interface = NULL;
 interface_base_t *chosen_interface = NULL;
 
 void jtag_set_error(int error)
@@ -1329,22 +1329,91 @@ void jtag_tap_free(jtag_tap_t *tap)
 	free(tap);
 }
 
+int interface_init(struct command_context_s *cmd_ctx)
+{
+  int retval;
+  if(interface)
+    return ERROR_OK;
+
+  if(!chosen_interface){
+    /* nothing was previously specified by "interface" command */
+    LOG_ERROR("An interface has to be specified, see \"interface\" command");
+    return ERROR_JTAG_INVALID_INTERFACE;
+  }
+
+  switch(chosen_interface->type){
+  case INTERFACE_SWD:
+    retval=swd_interface_init(cmd_ctx);
+  case INTERFACE_JTAG:
+  default:
+    retval=jtag_interface_init(cmd_ctx);
+  }
+  return retval;
+}
+
 int jtag_interface_init(struct command_context_s *cmd_ctx)
 {
-	if (jtag)
+	if (interface)
 		return ERROR_OK;
 
-	if (!jtag_interface)
+	if (!chosen_interface)
 	{
 		/* nothing was previously specified by "interface" command */
 		LOG_ERROR("JTAG interface has to be specified, see \"interface\" command");
 		return ERROR_JTAG_INVALID_INTERFACE;
 	}
 
+	interface = chosen_interface;
+
+	jtag_interface_t *jtag_interface = (jtag_interface_t *)chosen_interface;
 	jtag = jtag_interface;
 	if (jtag_interface->init() != ERROR_OK)
 	{
 		jtag = NULL;
+		interface = NULL;
+		return ERROR_JTAG_INIT_FAILED;
+	}
+
+	int requested_khz = jtag_get_speed_khz();
+	int actual_khz = requested_khz;
+	int retval = jtag_get_speed_readable(&actual_khz);
+	if (ERROR_OK != retval)
+		LOG_INFO("interface specific clock speed value %d", jtag_get_speed());
+	else if (actual_khz)
+	{
+		if ((CLOCK_MODE_RCLK == clock_mode)
+			|| ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz))
+		{
+			LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
+				, actual_khz);
+		}
+		else
+			LOG_INFO("clock speed %d kHz", actual_khz);
+	}
+	else
+		LOG_INFO("RCLK (adaptive clock speed)");
+
+	return ERROR_OK;
+}
+
+int swd_interface_init(struct command_context_s *cmd_ctx)
+{
+	if (interface)
+		return ERROR_OK;
+
+	if (!chosen_interface)
+	{
+		/* nothing was previously specified by "interface" command */
+		LOG_ERROR("SWD interface has to be specified, see \"interface\" command");
+		return ERROR_JTAG_INVALID_INTERFACE;
+	}
+
+	interface = chosen_interface;
+
+	swd_interface_t *swd_interface = (swd_interface_t*)interface;
+	if (swd_interface->init() != ERROR_OK)
+	{
+		interface = NULL;
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 1dfefde..64587a5 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -323,7 +323,9 @@ bool jtag_will_verify_capture_ir(void);
  * Initialize interface upon startup.  Return a successful no-op upon
  * subsequent invocations.
  */
+int  interface_init(struct command_context_s* cmd_ctx);
 int  jtag_interface_init(struct command_context_s* cmd_ctx);
+int  swd_interface_init(struct command_context_s* cmd_ctx);
 
 /// Shutdown the JTAG interface upon program exit.
 int  jtag_interface_quit(void);
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index c938acc..7bb60dd 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -50,6 +50,7 @@ static const Jim_Nvp nvp_jtag_tap_event[] = {
 };
 
 extern jtag_interface_t *jtag_interface;
+extern interface_base_t *chosen_interface;
 
 enum jtag_tap_cfg_param {
 	JCFG_EVENT
@@ -422,7 +423,7 @@ static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 			Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
 			return JIM_ERR;
 		}
-		const char *name = jtag_interface ? jtag_interface->name : NULL;
+		const char *name = chosen_interface ? chosen_interface->name : NULL;
 		Jim_SetResultString(goi.interp, name ? : "undefined", -1);
 		return JIM_OK;
 	case JTAG_CMD_INIT:
@@ -628,7 +629,7 @@ COMMAND_HANDLER(handle_interface_list_command)
 COMMAND_HANDLER(handle_interface_command)
 {
 	/* check whether the interface is already configured */
-	if (jtag_interface)
+	if (chosen_interface)
 	{
 		LOG_WARNING("Interface already configured, ignoring");
 		return ERROR_OK;
@@ -647,7 +648,9 @@ COMMAND_HANDLER(handle_interface_command)
 		if (ERROR_OK != retval)
 				return retval;
 
-		jtag_interface = jtag_interfaces[i];
+		jtag_interface_t *jtag_interface = jtag_interfaces[i];
+		jtag_interface->type = INTERFACE_JTAG;
+                chosen_interface = (interface_base_t *)jtag_interfaces[i];
 
 		if (jtag_interface->khz == NULL)
 			jtag_interface->khz = default_khz;
@@ -660,6 +663,31 @@ COMMAND_HANDLER(handle_interface_command)
 
 		return ERROR_OK;
 	}
+	
+	for (unsigned i = 0; NULL != swd_interfaces[i]; i++)
+        {
+                if (strcmp(args[0], swd_interfaces[i]->name) != 0)
+                        continue;
+
+                int retval = swd_interfaces[i]->register_commands(cmd_ctx);
+                if (ERROR_OK != retval)
+                                return retval;
+
+                swd_interface_t *swd_interface = swd_interfaces[i]; 
+                swd_interface->type = INTERFACE_SWD;
+                chosen_interface = (interface_base_t *)swd_interface;
+
+                if (swd_interface->khz == NULL)
+                        swd_interface->khz = default_khz;
+                if (swd_interface->speed_div == NULL)
+                        swd_interface->speed_div = default_speed_div;
+                if (swd_interface->power_dropout == NULL)
+                        swd_interface->power_dropout = default_power_dropout;
+                if (swd_interface->srst_asserted == NULL)
+                        swd_interface->srst_asserted = default_srst_asserted;
+
+                return ERROR_OK;
+        }
 
 	/* no valid interface was found (i.e. the configuration option,
 	 * didn't match one of the compiled-in interfaces
diff --git a/src/openocd.c b/src/openocd.c
index d67ebd5..e982a1b 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -128,12 +128,12 @@ COMMAND_HANDLER(handle_init_command)
 		return ERROR_FAIL;
 	LOG_DEBUG("target init complete");
 
-	if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
+	if ((retval = interface_init(cmd_ctx)) != ERROR_OK)
 	{
-		/* we must be able to set up the jtag interface */
+		/* we must be able to set up the interface */
 		return retval;
 	}
-	LOG_DEBUG("jtag interface init complete");
+	LOG_DEBUG("interface init complete");
 
 	/* Try to initialize & examine the JTAG chain at this point, but
 	 * continue startup regardless */
diff --git a/tcl/interface/rlink-swd.cfg b/tcl/interface/rlink-swd.cfg
new file mode 100644
index 0000000..ef06173
--- /dev/null
+++ b/tcl/interface/rlink-swd.cfg
@@ -0,0 +1,8 @@
+#
+# Raisonance RLink
+#
+# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html
+#
+
+interface rlink-swd
+
-- 
1.6.0.6

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to