Added ft2232_transfer() and ft2232_bitbang() implementation. New interface routines...
[openocd/libswd.git] / src / interface / interface_signal.c
blob7b4423c168b1bd6f797c8ec8b86174f740c28c68
1 /*
2 * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO
3 * cederom@tlen.pl, http://www.tomek.cedro.info
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 /** @file: Generic OpenOCD interface. */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include <interface/interface.h>
27 #include <jtag/interface.h>
28 #include <helper/log.h>
30 extern struct jtag_interface *jtag_interface;
32 /******************************************************************************
33 * SIGNAL INFRASTRUCTURE AND OPERATIONS
34 ******************************************************************************/
36 /** Check if specified signal is already defined (case insensitive) and return
37 * its pointer if defined.
38 * \param *name signal name to check
39 * \return pointer to signal structure in memory if found, NULL otherwise.
41 oocd_interface_signal_t *oocd_interface_signal_find(char *name)
43 /* LOG_DEBUG("Searching for interface signal \"%s\"", name); */
44 /* Check if interface already exists */
45 if (!jtag_interface) {
46 LOG_ERROR("Interface does not yet exist!");
47 return NULL;
49 /* Check if interface signal to already exists */
50 if (!jtag_interface->signal) {
51 LOG_DEBUG("No interface signals defined (yet?).");
52 return NULL;
54 /* Check if signal name is correct */
55 if (!name || strncmp(name, " ", 1) == 0) {
56 LOG_ERROR("Interface signal name cannot be empty.");
57 return NULL;
59 /* Check if signal name already exist */
60 oocd_interface_signal_t *sig;
61 sig = jtag_interface->signal;
62 while (sig) {
63 if (!strncasecmp(sig->name, name, 32)) {
64 LOG_DEBUG("Interface signal %s found.", sig->name);
65 return sig;
67 sig = sig->next;
69 /* If signal is not found return null pointer. */
70 LOG_WARNING("Interface signal %s not found.", name);
71 return NULL;
73 /** Add new signal to the interface.
74 * Signal will be allocated in memory with provided name and mask.
75 * There is no sense for giving value field at this time because signal create
76 * can take place during initialization where interface is not yet ready, also
77 * they can be used for read and write, so this is higher level script task
78 * to initialize their default value with appropriate 'bitbang' call.
79 * The default value for new signal equals provided mask to maintain Hi-Z.
81 * \param *name is the signal name (max 32 char).
82 * \param mask is the signal mask (unsigned int).
83 * \param value is the initial value for signal to set.
84 * \return ERROR_OK on success or ERROR_FAIL on failure.
86 int oocd_interface_signal_add(char *name, unsigned int mask)
88 LOG_DEBUG("Adding signal \"%s\"", name);
89 /* Check if interface already exists */
90 if (!jtag_interface) {
91 LOG_ERROR("Interface does not yet exist!");
92 return ERROR_FAIL;
95 /* Check if name is correct string */
96 if (!name || strncmp(name, " ", 1) == 0) {
97 LOG_ERROR("Signal name cannot be empty");
98 return ERROR_FAIL;
101 oocd_interface_signal_t *newsignal, *lastsignal;
102 int snlen;
104 /* Check signal length (min=1, max=32 characters) */
105 snlen = strnlen(name, 32);
106 if (snlen < 1 || snlen > 32) {
107 LOG_ERROR("Signal name too short or too long!");
108 return ERROR_FAIL;
111 /* Check if signal name already exist and return error if so */
112 if (oocd_interface_signal_find(name)) {
113 LOG_ERROR("Specified signal already exist!");
114 return ERROR_FAIL;
117 /* Allocate memory for new signal structure */
118 newsignal = (oocd_interface_signal_t *)calloc(1, sizeof(oocd_interface_signal_t));
119 if (!newsignal) {
120 LOG_ERROR("cannot allocate memory for new signal: %s", name);
121 return ERROR_FAIL;
123 newsignal->name = (char *)calloc(1, snlen+1);
124 if (!newsignal->name) {
125 LOG_ERROR("cannot allocate memory for signal %s name", name);
126 return ERROR_FAIL;
129 /* Initialize structure data and return or break on error */
130 for (;;) {
131 if (!strncpy(newsignal->name, name, snlen)) {
132 LOG_ERROR("cannot copy signal %s name!", name);
133 break;
136 newsignal->mask = mask;
137 newsignal->value = mask;
139 if (!jtag_interface->signal) {
140 jtag_interface->signal = newsignal;
141 } else {
142 lastsignal = jtag_interface->signal;
143 while (lastsignal->next)
144 lastsignal = lastsignal->next;
145 lastsignal->next = newsignal;
147 LOG_DEBUG("Signal \"%s\" added.", name);
148 return ERROR_OK;
151 /* If there was an error free up resources and return error */
152 free(newsignal->name);
153 free(newsignal);
154 return ERROR_FAIL;
157 /** Delete interface signal.
158 * Removes signal from singly linked list of interface signals and free memory.
159 * \param name is the name of the signal to remove.
160 * \return ERROR_OK on success, ERROR_FAIL on failure.
162 int oocd_interface_signal_del(char *name)
164 LOG_DEBUG("Deleting signal \"%s\"", name);
165 /* Check if interface already exists */
166 if (!jtag_interface) {
167 LOG_ERROR("Interface does not yet exist!");
168 return ERROR_FAIL;
170 /* Check if interface any signal exist */
171 if (!jtag_interface->signal) {
172 LOG_ERROR("Signal list is empty!");
173 return ERROR_FAIL;
176 /* Check if signal name is correct */
177 if (!name || strncmp(name, " ", 1) == 0) {
178 LOG_ERROR("Signal name cannot be empty.");
179 return ERROR_FAIL;
182 oocd_interface_signal_t *delsig = NULL, *prevsig = NULL;
184 /* look for the signal name on the list */
185 delsig = oocd_interface_signal_find(name);
187 /* return error if signal is not on the list */
188 if (!delsig) {
189 LOG_ERROR("Signal not found!");
190 return ERROR_FAIL;
193 /* detach signal to be removed from the list */
194 prevsig = jtag_interface->signal;
195 if (prevsig == delsig) {
196 /* we need to detach first signal on the list */
197 jtag_interface->signal = jtag_interface->signal->next;
198 } else {
199 for (; prevsig->next; prevsig = prevsig->next) {
200 if (prevsig->next == delsig) {
201 prevsig->next = prevsig->next->next;
202 break;
207 /* now free memory of detached element */
208 free(delsig->name);
209 free(delsig);
210 LOG_DEBUG("Signal \"%s\" removed.", name);
211 return ERROR_OK;