This is an automated email from Gerrit. Tomasz CEDRO ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/1069
-- gerrit commit 87f7c4923f29bb8defc4162a1d258da96baa8168 Author: Tomek CEDRO <[email protected]> Date: Sat Nov 10 18:58:27 2012 +0100 Small file rename. When proper source code directory structure is implemented filenames need no prefix, I guess :-) Change-Id: Ib77e2a362a35c886d7ce8efb745bb1c813e61b72 Signed-off-by: Tomek CEDRO <[email protected]> diff --git a/src/interface/Makefile.am b/src/interface/Makefile.am index 2d0dd06..ed73ee5 100644 --- a/src/interface/Makefile.am +++ b/src/interface/Makefile.am @@ -15,13 +15,13 @@ BUILT_SOURCES += CLEANFILES += liboocdinterface_la_SOURCES = \ - interface_signal.c \ - interface_bitbang.c + signal.c \ + bitbang.c noinst_HEADERS = \ interface.h \ - interface_signal.h \ - interface_bitbang.h + signal.h \ + bitbang.h EXTRA_DIST = diff --git a/src/interface/bitbang.c b/src/interface/bitbang.c new file mode 100644 index 0000000..fb55bcb --- /dev/null +++ b/src/interface/bitbang.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011-2012 Tomasz Boleslaw CEDRO + * [email protected], http://www.tomek.cedro.info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/** @file Framework to bitbang the interface pins, body file. */ + +#include <helper/command.h> +#include <interface/interface.h> + +extern struct jtag_interface *jtag_interface; + +/*-----------------------------------------------------------------------*/ + +/****************************************************************************** + * TCL INTERFACE TO INTERFACE_BITBANG OPERATIONS (DECLARED IN DRIVER) + ******************************************************************************/ + +/** Bitbang framework allows operation on interface signals, operating on HEX + * values, to read and set their state. When only signal name is given then + * read operation is performed and value returned for given port mask defined + * by signal mask. Additional '=' parameter with following value with set this + * value to the port (again restricted by the signal mask). Therefore it is + * possible to set/get more than one bit/pin at once each with its own value. + * In addition label 'hi'/'set' equals value 0xFFFFFFFF, 'lo'/'clr' equals 0. + * Also note that read/write operation will affect selected port bits direction + * as reading values will switch masked bits to input while writing will make + * them outputs. This is also good way to change port behavior for some pins, + * but beware that reading output may not always bring expected results as it + * may impact device connected to that pin (i.e. Hi-Z input gives 1 undriven). + * This functionality brings new possibilities to script additional features. + */ +COMMAND_HANDLER(handle_oocd_interface_bitbang_command) +{ + LOG_DEBUG("%s", __func__); + + if (!jtag_interface) { + LOG_ERROR("You need to select interface first!"); + return ERROR_FAIL; + } + + if (!jtag_interface->bitbang) { + LOG_ERROR("This interface does not support bit-banging!"); + return ERROR_FAIL; + } + + if (CMD_ARGC < 1) { + LOG_ERROR("Bad syntax!"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (jtag_interface->signal == NULL) { + LOG_ERROR("No signals defined, see 'interface_signal' command for help."); + return ERROR_FAIL; + } + + static oocd_interface_signal_t *sig; + static unsigned int pn; + static int retval; + static char *mark, *signame, *sigval, pcmd[OOCD_BITBANG_PARAM_CMD_MAX_LEN]; + + /* Iterate through list of command parameters */ + for (pn = 0; pn < CMD_ARGC; pn++) { + /* Make a local copy of parameter command to work on */ + if (!strncpy(pcmd, CMD_ARGV[pn], OOCD_BITBANG_PARAM_CMD_MAX_LEN)) { + LOG_ERROR("Cannot copy parameter: %s", CMD_ARGV[pn]); + return ERROR_FAIL; + } + /* Look for '=' mark to see if read or write will happen */ + mark = strstr(pcmd, "="); + if (!mark) { + /* If no '=' was found then we read the signal value */ + /* Check if specified signal exists */ + sig = oocd_interface_signal_find(pcmd); + if (!sig) { + LOG_ERROR("Unknown signal specified!"); + return ERROR_FAIL; + } + /* Call the driver routine to do the actual signal read */ + retval = jtag_interface->bitbang(NULL, pcmd, 1, (int *)&sig->value); + if (retval != ERROR_OK) { + LOG_ERROR("Unable to read signal: %s", pcmd); + return ERROR_FAIL; + } + } else { + /* If '=' was found then we write specified value to the specified signal */ + /* Get and verify the signal name first */ + signame = strtok(pcmd, "="); + sig = oocd_interface_signal_find(signame); + if (!sig) { + LOG_ERROR("Unknown signal specified!"); + return ERROR_FAIL; + } + /* Then read the HEX value or hi (all bits one) / lo (all bits zero) */ + sigval = strtok(NULL, "="); + if (!sigval) { + LOG_ERROR("No value specified! Use: hi, set, lo, clr, or HEX port value."); + return ERROR_COMMAND_SYNTAX_ERROR; + } + if (!strncmp(sigval, "hi", 2) || !strncmp(sigval, "set", 3)) { + sig->value = 0xffffffff & sig->mask; + } else if (!strncmp(sigval, "lo", 2) || !strncmp(sigval, "clr", 3)) { + sig->value = 0; + } else if (!sscanf(sigval, "%x", (unsigned int *)&sig->value)) { + LOG_ERROR("Bad value parameter specified (can be: hi, set, lo, clr, or direct HEX port value)"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + retval = jtag_interface->bitbang(NULL, signame, 0, (int *)&sig->value); + if (retval != ERROR_OK) { + LOG_ERROR("Unable to write signal: %s", signame); + return ERROR_FAIL; + } + } + command_print(CMD_CTX, "%s=0x%08X", sig->name, sig->value); + } + return ERROR_OK; +} + +static const struct command_registration oocd_interface_bitbang_commands[] = { + { + .name = "interface_bitbang", + .handler = handle_oocd_interface_bitbang_command, + .mode = COMMAND_EXEC, + .help = "Perform bit-bang operations on interface signal (mask!).", + .usage = "'signal_name' to read, 'signal_name'='port_hex_value' to write.", + }, + COMMAND_REGISTRATION_DONE +}; + +int oocd_interface_bitbang_register_commands(struct command_context *ctx) +{ + return register_commands(ctx, NULL, oocd_interface_bitbang_commands); +}; diff --git a/src/interface/bitbang.h b/src/interface/bitbang.h new file mode 100644 index 0000000..1ed20ba --- /dev/null +++ b/src/interface/bitbang.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011-2012 Tomasz Boleslaw CEDRO + * [email protected], http://www.tomek.cedro.info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** @file Framework to work with interface signals, header file. */ + +#ifndef OOCD_INTERFACE_BITBANG_H +#define OOCD_INTERFACE_BITBANG_H + +#define OOCD_BITBANG_PARAM_CMD_MAX_LEN 45 +int oocd_interface_bitbang_register_commands(struct command_context *ctx); + +#endif diff --git a/src/interface/interface.h b/src/interface/interface.h index d1e6d72..450759e 100644 --- a/src/interface/interface.h +++ b/src/interface/interface.h @@ -22,7 +22,7 @@ #ifndef OOCD_INTERFACE_H #define OOCD_INTERFACE_H -#include <interface/interface_signal.h> -#include <interface/interface_bitbang.h> +#include <interface/signal.h> +#include <interface/bitbang.h> #endif diff --git a/src/interface/interface_bitbang.c b/src/interface/interface_bitbang.c deleted file mode 100644 index fb55bcb..0000000 --- a/src/interface/interface_bitbang.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2011-2012 Tomasz Boleslaw CEDRO - * [email protected], http://www.tomek.cedro.info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/** @file Framework to bitbang the interface pins, body file. */ - -#include <helper/command.h> -#include <interface/interface.h> - -extern struct jtag_interface *jtag_interface; - -/*-----------------------------------------------------------------------*/ - -/****************************************************************************** - * TCL INTERFACE TO INTERFACE_BITBANG OPERATIONS (DECLARED IN DRIVER) - ******************************************************************************/ - -/** Bitbang framework allows operation on interface signals, operating on HEX - * values, to read and set their state. When only signal name is given then - * read operation is performed and value returned for given port mask defined - * by signal mask. Additional '=' parameter with following value with set this - * value to the port (again restricted by the signal mask). Therefore it is - * possible to set/get more than one bit/pin at once each with its own value. - * In addition label 'hi'/'set' equals value 0xFFFFFFFF, 'lo'/'clr' equals 0. - * Also note that read/write operation will affect selected port bits direction - * as reading values will switch masked bits to input while writing will make - * them outputs. This is also good way to change port behavior for some pins, - * but beware that reading output may not always bring expected results as it - * may impact device connected to that pin (i.e. Hi-Z input gives 1 undriven). - * This functionality brings new possibilities to script additional features. - */ -COMMAND_HANDLER(handle_oocd_interface_bitbang_command) -{ - LOG_DEBUG("%s", __func__); - - if (!jtag_interface) { - LOG_ERROR("You need to select interface first!"); - return ERROR_FAIL; - } - - if (!jtag_interface->bitbang) { - LOG_ERROR("This interface does not support bit-banging!"); - return ERROR_FAIL; - } - - if (CMD_ARGC < 1) { - LOG_ERROR("Bad syntax!"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (jtag_interface->signal == NULL) { - LOG_ERROR("No signals defined, see 'interface_signal' command for help."); - return ERROR_FAIL; - } - - static oocd_interface_signal_t *sig; - static unsigned int pn; - static int retval; - static char *mark, *signame, *sigval, pcmd[OOCD_BITBANG_PARAM_CMD_MAX_LEN]; - - /* Iterate through list of command parameters */ - for (pn = 0; pn < CMD_ARGC; pn++) { - /* Make a local copy of parameter command to work on */ - if (!strncpy(pcmd, CMD_ARGV[pn], OOCD_BITBANG_PARAM_CMD_MAX_LEN)) { - LOG_ERROR("Cannot copy parameter: %s", CMD_ARGV[pn]); - return ERROR_FAIL; - } - /* Look for '=' mark to see if read or write will happen */ - mark = strstr(pcmd, "="); - if (!mark) { - /* If no '=' was found then we read the signal value */ - /* Check if specified signal exists */ - sig = oocd_interface_signal_find(pcmd); - if (!sig) { - LOG_ERROR("Unknown signal specified!"); - return ERROR_FAIL; - } - /* Call the driver routine to do the actual signal read */ - retval = jtag_interface->bitbang(NULL, pcmd, 1, (int *)&sig->value); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to read signal: %s", pcmd); - return ERROR_FAIL; - } - } else { - /* If '=' was found then we write specified value to the specified signal */ - /* Get and verify the signal name first */ - signame = strtok(pcmd, "="); - sig = oocd_interface_signal_find(signame); - if (!sig) { - LOG_ERROR("Unknown signal specified!"); - return ERROR_FAIL; - } - /* Then read the HEX value or hi (all bits one) / lo (all bits zero) */ - sigval = strtok(NULL, "="); - if (!sigval) { - LOG_ERROR("No value specified! Use: hi, set, lo, clr, or HEX port value."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (!strncmp(sigval, "hi", 2) || !strncmp(sigval, "set", 3)) { - sig->value = 0xffffffff & sig->mask; - } else if (!strncmp(sigval, "lo", 2) || !strncmp(sigval, "clr", 3)) { - sig->value = 0; - } else if (!sscanf(sigval, "%x", (unsigned int *)&sig->value)) { - LOG_ERROR("Bad value parameter specified (can be: hi, set, lo, clr, or direct HEX port value)"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - retval = jtag_interface->bitbang(NULL, signame, 0, (int *)&sig->value); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to write signal: %s", signame); - return ERROR_FAIL; - } - } - command_print(CMD_CTX, "%s=0x%08X", sig->name, sig->value); - } - return ERROR_OK; -} - -static const struct command_registration oocd_interface_bitbang_commands[] = { - { - .name = "interface_bitbang", - .handler = handle_oocd_interface_bitbang_command, - .mode = COMMAND_EXEC, - .help = "Perform bit-bang operations on interface signal (mask!).", - .usage = "'signal_name' to read, 'signal_name'='port_hex_value' to write.", - }, - COMMAND_REGISTRATION_DONE -}; - -int oocd_interface_bitbang_register_commands(struct command_context *ctx) -{ - return register_commands(ctx, NULL, oocd_interface_bitbang_commands); -}; diff --git a/src/interface/interface_bitbang.h b/src/interface/interface_bitbang.h deleted file mode 100644 index 1ed20ba..0000000 --- a/src/interface/interface_bitbang.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2011-2012 Tomasz Boleslaw CEDRO - * [email protected], http://www.tomek.cedro.info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file Framework to work with interface signals, header file. */ - -#ifndef OOCD_INTERFACE_BITBANG_H -#define OOCD_INTERFACE_BITBANG_H - -#define OOCD_BITBANG_PARAM_CMD_MAX_LEN 45 -int oocd_interface_bitbang_register_commands(struct command_context *ctx); - -#endif diff --git a/src/interface/interface_signal.c b/src/interface/interface_signal.c deleted file mode 100644 index e32eb0a..0000000 --- a/src/interface/interface_signal.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO - * [email protected], http://www.tomek.cedro.info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file: Generic OpenOCD interface. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <interface/interface.h> -#include <helper/log.h> - -extern struct jtag_interface *jtag_interface; - -/****************************************************************************** - * SIGNAL INFRASTRUCTURE AND OPERATIONS - ******************************************************************************/ - -/** Check if specified signal is already defined (case insensitive) and return - * its pointer if defined. - * \param *name signal name to check - * \return pointer to signal structure in memory if found, NULL otherwise. - */ -oocd_interface_signal_t *oocd_interface_signal_find(char *name) -{ - /* LOG_DEBUG("Searching for interface signal \"%s\"", name); */ - /* Check if interface already exists */ - if (!jtag_interface) { - LOG_ERROR("Interface does not yet exist!"); - return NULL; - } - /* Check if interface signal to already exists */ - if (!jtag_interface->signal) { - LOG_DEBUG("No interface signals defined (yet?)."); - return NULL; - } - /* Check if signal name is correct */ - if (!name || strncmp(name, " ", 1) == 0) { - LOG_ERROR("Interface signal name cannot be empty."); - return NULL; - } - /* Check if signal name already exist */ - oocd_interface_signal_t *sig; - sig = jtag_interface->signal; - while (sig) { - if (!strncasecmp(sig->name, name, 32)) { - LOG_DEBUG("Interface signal %s found.", sig->name); - return sig; - } - sig = sig->next; - } - /* If signal is not found return null pointer. */ - LOG_WARNING("Interface signal %s not found.", name); - return NULL; -} -/** Add new signal to the interface. - * Signal will be allocated in memory with provided name and mask. - * There is no sense for giving value field at this time because signal create - * can take place during initialization where interface is not yet ready, also - * they can be used for read and write, so this is higher level script task - * to initialize their default value with appropriate 'bitbang' call. - * The default value for new signal equals provided mask to maintain Hi-Z. - * - * \param *name is the signal name (max 32 char). - * \param mask is the signal mask (unsigned int). - * \param value is the initial value for signal to set. - * \return ERROR_OK on success or ERROR_FAIL on failure. - */ -int oocd_interface_signal_add(char *name, unsigned int mask) -{ - LOG_DEBUG("Adding signal \"%s\"", name); - /* Check if interface already exists */ - if (!jtag_interface) { - LOG_ERROR("Interface does not yet exist!"); - return ERROR_FAIL; - } - - /* Check if name is correct string */ - if (!name || strncmp(name, " ", 1) == 0) { - LOG_ERROR("Signal name cannot be empty"); - return ERROR_FAIL; - } - - oocd_interface_signal_t *newsignal, *lastsignal; - int snlen; - - /* Check signal length (min=1, max=32 characters) */ - snlen = strnlen(name, 32); - if (snlen < 1 || snlen > 32) { - LOG_ERROR("Signal name too short or too long!"); - return ERROR_FAIL; - } - - /* Check if signal name already exist and return error if so */ - if (oocd_interface_signal_find(name)) { - LOG_ERROR("Specified signal already exist!"); - return ERROR_FAIL; - } - - /* Allocate memory for new signal structure */ - newsignal = (oocd_interface_signal_t *)calloc(1, sizeof(oocd_interface_signal_t)); - if (!newsignal) { - LOG_ERROR("cannot allocate memory for new signal: %s", name); - return ERROR_FAIL; - } - newsignal->name = (char *)calloc(1, snlen + 1); - if (!newsignal->name) { - LOG_ERROR("cannot allocate memory for signal %s name", name); - return ERROR_FAIL; - } - - /* Initialize structure data and return or break on error */ - for (;;) { - if (!strncpy(newsignal->name, name, snlen)) { - LOG_ERROR("cannot copy signal %s name!", name); - break; - } - - newsignal->mask = mask; - newsignal->value = mask; - - if (!jtag_interface->signal) { - jtag_interface->signal = newsignal; - } else { - lastsignal = jtag_interface->signal; - while (lastsignal->next) - lastsignal = lastsignal->next; - lastsignal->next = newsignal; - } - LOG_DEBUG("Signal \"%s\" added.", name); - return ERROR_OK; - } - - /* If there was an error free up resources and return error */ - free(newsignal->name); - free(newsignal); - return ERROR_FAIL; -} - -/** Delete interface signal. - * Removes signal from singly linked list of interface signals and free memory. - * \param name is the name of the signal to remove. - * \return ERROR_OK on success, ERROR_FAIL on failure. - */ -int oocd_interface_signal_del(char *name) -{ - LOG_DEBUG("Deleting signal \"%s\"", name); - /* Check if interface already exists */ - if (!jtag_interface) { - LOG_ERROR("Interface does not yet exist!"); - return ERROR_FAIL; - } - /* Check if interface any signal exist */ - if (!jtag_interface->signal) { - LOG_ERROR("Signal list is empty!"); - return ERROR_FAIL; - } - - /* Check if signal name is correct */ - if (!name || strncmp(name, " ", 1) == 0) { - LOG_ERROR("Signal name cannot be empty."); - return ERROR_FAIL; - } - - oocd_interface_signal_t *delsig = NULL, *prevsig = NULL; - - /* look for the signal name on the list */ - delsig = oocd_interface_signal_find(name); - - /* return error if signal is not on the list */ - if (!delsig) { - LOG_ERROR("Signal not found!"); - return ERROR_FAIL; - } - - /* detach signal to be removed from the list */ - prevsig = jtag_interface->signal; - if (prevsig == delsig) { - /* we need to detach first signal on the list */ - jtag_interface->signal = jtag_interface->signal->next; - } else { - for (; prevsig->next; prevsig = prevsig->next) { - if (prevsig->next == delsig) { - prevsig->next = prevsig->next->next; - break; - } - } - } - - /* now free memory of detached element */ - free(delsig->name); - free(delsig); - LOG_DEBUG("Signal \"%s\" removed.", name); - return ERROR_OK; -} - -/****************************************************************************** - * TCL INTERFACE TO INTERFACE_SIGNAL INFRASTRUCTURE AND OPERATIONS - ******************************************************************************/ - -/** Interface signals handling routine that can add, delete and list signals. - * Signal ADD requires signal name string and 32-bit mask, optionally a value. - * Values are read as HEX. Signal DEL requires only signal name to delete. - * Signal LIST will show marvelous table wits signal names, masks and values. - * Interfaces should be defined in configuration file by TCL interface. - * Parameters are checked before function execution. - */ -COMMAND_HANDLER(handle_oocd_interface_signal_command) -{ - LOG_DEBUG("entering function..."); - - if (!jtag_interface) { - command_print(CMD_CTX, "You must initialize interface first!"); - return ERROR_FAIL; - } - - if (CMD_ARGC < 1 || CMD_ARGC > 3) { - command_print(CMD_CTX, "Bad syntax!"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - int sigmask; - char signame[32]; - - if (!strncasecmp(CMD_ARGV[0], "add", 3)) { - if (CMD_ARGC < 3) { - LOG_ERROR("Usage: interface_signal add signal_name signal_mask"); - return ERROR_FAIL; - } - if (!strncpy(signame, CMD_ARGV[1], 32)) { - LOG_ERROR("Unable to copy signal name from parameter list!"); - return ERROR_FAIL; - } - /* We are going to add interface signal. */ - /* Check the mask parameter. */ - if (!sscanf(CMD_ARGV[2], "%x", &sigmask)) { - LOG_ERROR("Bad signal mask parameter! Use HEX value."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - /* Now add the inetrface signal with specified parameters. */ - return oocd_interface_signal_add(signame, sigmask); - - } else if (!strncasecmp(CMD_ARGV[0], "del", 3)) { - if (CMD_ARGC < 2) { - LOG_ERROR("Usage: interface_signal del signal_name"); - return ERROR_FAIL; - } - /* We are going to delete specified signal. */ - return oocd_interface_signal_del((char *)CMD_ARGV[1]); - - } else if (!strncasecmp(CMD_ARGV[0], "list", 4)) { - /* We are going to list available signals. */ - oocd_interface_signal_t *sig; - sig = jtag_interface->signal; - command_print(CMD_CTX, " Interface Signal Name | Mask | Value "); - command_print(CMD_CTX, "----------------------------------------------------------"); - while (sig) { - command_print(CMD_CTX, "%32s | 0x%08X | 0x%08X", sig->name, sig->mask, sig->value); - sig = sig->next; - } - /* Also print warning if interface driver does not support bit-baning. */ - if (!jtag_interface->bitbang) - command_print(CMD_CTX, "WARNING: This interface does not support bit-baning!"); - return ERROR_OK; - - } else if (!strncasecmp(CMD_ARGV[0], "find", 4)) { - if (CMD_ARGC < 2) { - LOG_ERROR("Usage: interface_signal find signal_name"); - return ERROR_FAIL; - } - /* Find the signal and print its details. */ - oocd_interface_signal_t *sig = oocd_interface_signal_find((char *)CMD_ARGV[1]); - if (sig != NULL) { - command_print(CMD_CTX, "%s: mask=0x%08X value=0x%08X", sig->name, sig->mask, sig->value); - return ERROR_OK; - } - /* Or return information and error if not found. */ - command_print(CMD_CTX, "Signal not found!"); - return ERROR_FAIL; - } - /* For unknown parameter print error and return error code. */ - command_print(CMD_CTX, "Unknown parameter!"); - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static const struct command_registration oocd_interface_signal_commands[] = { - { - .name = "interface_signal", - .handler = handle_oocd_interface_signal_command, - .mode = COMMAND_ANY, - .help = "List, Find, Remove and Add interface signal mask", - .usage = "(add|del|find|list) signal_name [mask]", - }, - COMMAND_REGISTRATION_DONE -}; - -int oocd_interface_signal_register_commands(struct command_context *ctx) -{ - return register_commands(ctx, NULL, oocd_interface_signal_commands); -} diff --git a/src/interface/interface_signal.h b/src/interface/interface_signal.h deleted file mode 100644 index 01ec11b..0000000 --- a/src/interface/interface_signal.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO - * [email protected], http://www.tomek.cedro.info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef OOCD_INTERFACE_SIGNAL_H -#define OOCD_INTERFACE_SIGNAL_H - -/** Some generic interface signal definitions. */ - -/** Interface Signal type declaration (single linked list element). */ -typedef struct oocd_interface_signal { - /** Signal name string. */ - char *name; - /** Mask value for selected signal. */ - unsigned int mask; - /** Value can be 0,1, or -1 for unknown state. */ - int value; - /** Pointer to the next element on the signals list. */ - struct oocd_interface_signal *next; -} oocd_interface_signal_t; - -typedef enum oocd_interface_operation { - UNDEFINED = 0, - READ, - WRITE, - SET, - CLEAR -} oocd_interface_operation_t; - -int oocd_interface_signal_add(char *name, unsigned int mask); -int oocd_interface_signal_del(char *name); -oocd_interface_signal_t *oocd_interface_signal_find(char *name); - -int oocd_interface_signal_register_commands(struct command_context *ctx); - -#endif diff --git a/src/interface/signal.c b/src/interface/signal.c new file mode 100644 index 0000000..e32eb0a --- /dev/null +++ b/src/interface/signal.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO + * [email protected], http://www.tomek.cedro.info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** @file: Generic OpenOCD interface. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <interface/interface.h> +#include <helper/log.h> + +extern struct jtag_interface *jtag_interface; + +/****************************************************************************** + * SIGNAL INFRASTRUCTURE AND OPERATIONS + ******************************************************************************/ + +/** Check if specified signal is already defined (case insensitive) and return + * its pointer if defined. + * \param *name signal name to check + * \return pointer to signal structure in memory if found, NULL otherwise. + */ +oocd_interface_signal_t *oocd_interface_signal_find(char *name) +{ + /* LOG_DEBUG("Searching for interface signal \"%s\"", name); */ + /* Check if interface already exists */ + if (!jtag_interface) { + LOG_ERROR("Interface does not yet exist!"); + return NULL; + } + /* Check if interface signal to already exists */ + if (!jtag_interface->signal) { + LOG_DEBUG("No interface signals defined (yet?)."); + return NULL; + } + /* Check if signal name is correct */ + if (!name || strncmp(name, " ", 1) == 0) { + LOG_ERROR("Interface signal name cannot be empty."); + return NULL; + } + /* Check if signal name already exist */ + oocd_interface_signal_t *sig; + sig = jtag_interface->signal; + while (sig) { + if (!strncasecmp(sig->name, name, 32)) { + LOG_DEBUG("Interface signal %s found.", sig->name); + return sig; + } + sig = sig->next; + } + /* If signal is not found return null pointer. */ + LOG_WARNING("Interface signal %s not found.", name); + return NULL; +} +/** Add new signal to the interface. + * Signal will be allocated in memory with provided name and mask. + * There is no sense for giving value field at this time because signal create + * can take place during initialization where interface is not yet ready, also + * they can be used for read and write, so this is higher level script task + * to initialize their default value with appropriate 'bitbang' call. + * The default value for new signal equals provided mask to maintain Hi-Z. + * + * \param *name is the signal name (max 32 char). + * \param mask is the signal mask (unsigned int). + * \param value is the initial value for signal to set. + * \return ERROR_OK on success or ERROR_FAIL on failure. + */ +int oocd_interface_signal_add(char *name, unsigned int mask) +{ + LOG_DEBUG("Adding signal \"%s\"", name); + /* Check if interface already exists */ + if (!jtag_interface) { + LOG_ERROR("Interface does not yet exist!"); + return ERROR_FAIL; + } + + /* Check if name is correct string */ + if (!name || strncmp(name, " ", 1) == 0) { + LOG_ERROR("Signal name cannot be empty"); + return ERROR_FAIL; + } + + oocd_interface_signal_t *newsignal, *lastsignal; + int snlen; + + /* Check signal length (min=1, max=32 characters) */ + snlen = strnlen(name, 32); + if (snlen < 1 || snlen > 32) { + LOG_ERROR("Signal name too short or too long!"); + return ERROR_FAIL; + } + + /* Check if signal name already exist and return error if so */ + if (oocd_interface_signal_find(name)) { + LOG_ERROR("Specified signal already exist!"); + return ERROR_FAIL; + } + + /* Allocate memory for new signal structure */ + newsignal = (oocd_interface_signal_t *)calloc(1, sizeof(oocd_interface_signal_t)); + if (!newsignal) { + LOG_ERROR("cannot allocate memory for new signal: %s", name); + return ERROR_FAIL; + } + newsignal->name = (char *)calloc(1, snlen + 1); + if (!newsignal->name) { + LOG_ERROR("cannot allocate memory for signal %s name", name); + return ERROR_FAIL; + } + + /* Initialize structure data and return or break on error */ + for (;;) { + if (!strncpy(newsignal->name, name, snlen)) { + LOG_ERROR("cannot copy signal %s name!", name); + break; + } + + newsignal->mask = mask; + newsignal->value = mask; + + if (!jtag_interface->signal) { + jtag_interface->signal = newsignal; + } else { + lastsignal = jtag_interface->signal; + while (lastsignal->next) + lastsignal = lastsignal->next; + lastsignal->next = newsignal; + } + LOG_DEBUG("Signal \"%s\" added.", name); + return ERROR_OK; + } + + /* If there was an error free up resources and return error */ + free(newsignal->name); + free(newsignal); + return ERROR_FAIL; +} + +/** Delete interface signal. + * Removes signal from singly linked list of interface signals and free memory. + * \param name is the name of the signal to remove. + * \return ERROR_OK on success, ERROR_FAIL on failure. + */ +int oocd_interface_signal_del(char *name) +{ + LOG_DEBUG("Deleting signal \"%s\"", name); + /* Check if interface already exists */ + if (!jtag_interface) { + LOG_ERROR("Interface does not yet exist!"); + return ERROR_FAIL; + } + /* Check if interface any signal exist */ + if (!jtag_interface->signal) { + LOG_ERROR("Signal list is empty!"); + return ERROR_FAIL; + } + + /* Check if signal name is correct */ + if (!name || strncmp(name, " ", 1) == 0) { + LOG_ERROR("Signal name cannot be empty."); + return ERROR_FAIL; + } + + oocd_interface_signal_t *delsig = NULL, *prevsig = NULL; + + /* look for the signal name on the list */ + delsig = oocd_interface_signal_find(name); + + /* return error if signal is not on the list */ + if (!delsig) { + LOG_ERROR("Signal not found!"); + return ERROR_FAIL; + } + + /* detach signal to be removed from the list */ + prevsig = jtag_interface->signal; + if (prevsig == delsig) { + /* we need to detach first signal on the list */ + jtag_interface->signal = jtag_interface->signal->next; + } else { + for (; prevsig->next; prevsig = prevsig->next) { + if (prevsig->next == delsig) { + prevsig->next = prevsig->next->next; + break; + } + } + } + + /* now free memory of detached element */ + free(delsig->name); + free(delsig); + LOG_DEBUG("Signal \"%s\" removed.", name); + return ERROR_OK; +} + +/****************************************************************************** + * TCL INTERFACE TO INTERFACE_SIGNAL INFRASTRUCTURE AND OPERATIONS + ******************************************************************************/ + +/** Interface signals handling routine that can add, delete and list signals. + * Signal ADD requires signal name string and 32-bit mask, optionally a value. + * Values are read as HEX. Signal DEL requires only signal name to delete. + * Signal LIST will show marvelous table wits signal names, masks and values. + * Interfaces should be defined in configuration file by TCL interface. + * Parameters are checked before function execution. + */ +COMMAND_HANDLER(handle_oocd_interface_signal_command) +{ + LOG_DEBUG("entering function..."); + + if (!jtag_interface) { + command_print(CMD_CTX, "You must initialize interface first!"); + return ERROR_FAIL; + } + + if (CMD_ARGC < 1 || CMD_ARGC > 3) { + command_print(CMD_CTX, "Bad syntax!"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + int sigmask; + char signame[32]; + + if (!strncasecmp(CMD_ARGV[0], "add", 3)) { + if (CMD_ARGC < 3) { + LOG_ERROR("Usage: interface_signal add signal_name signal_mask"); + return ERROR_FAIL; + } + if (!strncpy(signame, CMD_ARGV[1], 32)) { + LOG_ERROR("Unable to copy signal name from parameter list!"); + return ERROR_FAIL; + } + /* We are going to add interface signal. */ + /* Check the mask parameter. */ + if (!sscanf(CMD_ARGV[2], "%x", &sigmask)) { + LOG_ERROR("Bad signal mask parameter! Use HEX value."); + return ERROR_COMMAND_SYNTAX_ERROR; + } + /* Now add the inetrface signal with specified parameters. */ + return oocd_interface_signal_add(signame, sigmask); + + } else if (!strncasecmp(CMD_ARGV[0], "del", 3)) { + if (CMD_ARGC < 2) { + LOG_ERROR("Usage: interface_signal del signal_name"); + return ERROR_FAIL; + } + /* We are going to delete specified signal. */ + return oocd_interface_signal_del((char *)CMD_ARGV[1]); + + } else if (!strncasecmp(CMD_ARGV[0], "list", 4)) { + /* We are going to list available signals. */ + oocd_interface_signal_t *sig; + sig = jtag_interface->signal; + command_print(CMD_CTX, " Interface Signal Name | Mask | Value "); + command_print(CMD_CTX, "----------------------------------------------------------"); + while (sig) { + command_print(CMD_CTX, "%32s | 0x%08X | 0x%08X", sig->name, sig->mask, sig->value); + sig = sig->next; + } + /* Also print warning if interface driver does not support bit-baning. */ + if (!jtag_interface->bitbang) + command_print(CMD_CTX, "WARNING: This interface does not support bit-baning!"); + return ERROR_OK; + + } else if (!strncasecmp(CMD_ARGV[0], "find", 4)) { + if (CMD_ARGC < 2) { + LOG_ERROR("Usage: interface_signal find signal_name"); + return ERROR_FAIL; + } + /* Find the signal and print its details. */ + oocd_interface_signal_t *sig = oocd_interface_signal_find((char *)CMD_ARGV[1]); + if (sig != NULL) { + command_print(CMD_CTX, "%s: mask=0x%08X value=0x%08X", sig->name, sig->mask, sig->value); + return ERROR_OK; + } + /* Or return information and error if not found. */ + command_print(CMD_CTX, "Signal not found!"); + return ERROR_FAIL; + } + /* For unknown parameter print error and return error code. */ + command_print(CMD_CTX, "Unknown parameter!"); + return ERROR_COMMAND_SYNTAX_ERROR; +} + +static const struct command_registration oocd_interface_signal_commands[] = { + { + .name = "interface_signal", + .handler = handle_oocd_interface_signal_command, + .mode = COMMAND_ANY, + .help = "List, Find, Remove and Add interface signal mask", + .usage = "(add|del|find|list) signal_name [mask]", + }, + COMMAND_REGISTRATION_DONE +}; + +int oocd_interface_signal_register_commands(struct command_context *ctx) +{ + return register_commands(ctx, NULL, oocd_interface_signal_commands); +} diff --git a/src/interface/signal.h b/src/interface/signal.h new file mode 100644 index 0000000..01ec11b --- /dev/null +++ b/src/interface/signal.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO + * [email protected], http://www.tomek.cedro.info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef OOCD_INTERFACE_SIGNAL_H +#define OOCD_INTERFACE_SIGNAL_H + +/** Some generic interface signal definitions. */ + +/** Interface Signal type declaration (single linked list element). */ +typedef struct oocd_interface_signal { + /** Signal name string. */ + char *name; + /** Mask value for selected signal. */ + unsigned int mask; + /** Value can be 0,1, or -1 for unknown state. */ + int value; + /** Pointer to the next element on the signals list. */ + struct oocd_interface_signal *next; +} oocd_interface_signal_t; + +typedef enum oocd_interface_operation { + UNDEFINED = 0, + READ, + WRITE, + SET, + CLEAR +} oocd_interface_operation_t; + +int oocd_interface_signal_add(char *name, unsigned int mask); +int oocd_interface_signal_del(char *name); +oocd_interface_signal_t *oocd_interface_signal_find(char *name); + +int oocd_interface_signal_register_commands(struct command_context *ctx); + +#endif -- ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
