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
